[DRE-commits] [ruby-rspec] 10/25: New upstream 3.2.0+2+0+1+2

Cédric Boutillier boutil at moszumanska.debian.org
Sat Mar 28 20:34:11 UTC 2015


This is an automated email from the git hooks/post-receive script.

boutil pushed a commit to branch no_submodules
in repository ruby-rspec.

commit b998c4e6190be135360cc6dd0098dccceaea1df9
Author: Cédric Boutillier <boutil at debian.org>
Date:   Mon Mar 23 23:59:34 2015 +0100

    New upstream 3.2.0+2+0+1+2
---
 metadata.yml                                       |  106 -
 rspec-core/.document                               |    5 +
 rspec-core/.gitignore                              |   21 +
 rspec-core/.rspec                                  |    3 +
 rspec-core/.rubocop.yml                            |   53 +
 rspec-core/.rubocop_rspec_base.yml                 |  130 ++
 rspec-core/.travis.yml                             |   37 +
 rspec-core/.yardopts                               |    8 +
 rspec-core/Changelog.md                            | 1743 +++++++++++++++++
 rspec-core/DEV-README.md                           |   28 +
 rspec-core/Filtering.md                            |  161 ++
 rspec-core/Gemfile                                 |   35 +
 rspec-core/Gemfile-custom.sample                   |   19 +
 rspec-core/Guardfile                               |    5 +
 License.txt => rspec-core/License.txt              |    1 +
 rspec-core/README.md                               |  252 +++
 rspec-core/Rakefile                                |   85 +
 rspec-core/appveyor.yml                            |   34 +
 rspec-core/benchmarks/README.md                    |    4 +
 .../allocations/1000_groups_1_example.rb           |  124 ++
 .../allocations/1_group_1000_examples.rb           |   63 +
 rspec-core/benchmarks/allocations/helper.rb        |   30 +
 .../allocations/running_1000_groups_1_example.rb   |  100 +
 .../allocations/running_1_group_1000_examples.rb   |   60 +
 .../boot_time_with_many_load_path_dirs.sh          |  123 ++
 rspec-core/benchmarks/call_v_yield.rb              |   81 +
 rspec-core/benchmarks/capture_block_vs_yield.rb    |  208 ++
 rspec-core/benchmarks/check_inclusion.rb           |  125 ++
 .../define_method_v_attr_reader_v_def.rb           |   81 +
 rspec-core/benchmarks/eager_vs_lazy_metadata.rb    |  126 ++
 .../eager_vs_lazy_metadata/define_examples.rb      |   22 +
 rspec-core/benchmarks/filter_object.rb             |   35 +
 rspec-core/benchmarks/flat_map_vs_inject.rb        |   55 +
 rspec-core/benchmarks/index_v_take_while.rb        |   47 +
 .../map_then_flatten_vs_flat_map_benchmarks.rb     |   94 +
 .../benchmarks/module_inclusion_filtering.rb       |   89 +
 .../precalculate_absolute_file_path_or_not.rb      |   29 +
 .../benchmarks/require_relative_v_require.rb       |   75 +
 rspec-core/benchmarks/respond_to_v_defined.rb      |   72 +
 .../benchmarks/several_regexps_v_one_big_one.rb    |   86 +
 .../benchmarks/singleton_example_groups/helper.rb  |  120 ++
 .../singleton_example_groups/with_config_hooks.rb  |   28 +
 ...ule_inclusions_and_shared_context_inclusions.rb |   35 +
 .../with_module_inclusions.rb                      |   28 +
 .../with_no_config_hooks_or_inclusions.rb          |   22 +
 .../with_shared_context_inclusions.rb              |   28 +
 rspec-core/benchmarks/sort_by_v_shuffle.rb         |   83 +
 rspec-core/benchmarks/to_proc_v_not_to_proc.rb     |  539 ++++++
 rspec-core/cucumber.yml                            |    6 +
 rspec-core/exe/rspec                               |    4 +
 rspec-core/features/.nav                           |   62 +
 rspec-core/features/README.md                      |   13 +
 rspec-core/features/Upgrade.md                     |  352 ++++
 rspec-core/features/clear_examples.feature         |  107 +
 rspec-core/features/command_line/README.md         |   28 +
 rspec-core/features/command_line/dry_run.feature   |   29 +
 .../command_line/example_name_option.feature       |  100 +
 .../features/command_line/exit_status.feature      |   66 +
 rspec-core/features/command_line/fail_fast.feature |   27 +
 .../features/command_line/format_option.feature    |   86 +
 rspec-core/features/command_line/init.feature      |   50 +
 .../line_number_appended_to_path.feature           |  159 ++
 rspec-core/features/command_line/order.md          |   25 +
 .../features/command_line/pattern_option.feature   |   42 +
 rspec-core/features/command_line/rake_task.feature |  158 ++
 .../features/command_line/randomization.feature    |   65 +
 .../features/command_line/require_option.feature   |   45 +
 rspec-core/features/command_line/ruby.feature      |   27 +
 rspec-core/features/command_line/tag.feature       |  102 +
 .../features/command_line/warnings_option.feature  |   29 +
 .../configuration/alias_example_to.feature         |   57 +
 .../backtrace_exclusion_patterns.feature           |  154 ++
 .../features/configuration/custom_settings.feature |   84 +
 .../features/configuration/default_path.feature    |   37 +
 .../configuration/deprecation_stream.feature       |   87 +
 .../configuration/enable_global_dsl.feature        |   60 +
 .../features/configuration/exclude_pattern.feature |   43 +
 .../features/configuration/fail_fast.feature       |   79 +
 .../configuration/failure_exit_code.feature        |   53 +
 .../features/configuration/order_and_seed.feature  |    5 +
 .../features/configuration/output_stream.feature   |   27 +
 .../overriding_global_ordering.feature             |   90 +
 rspec-core/features/configuration/pattern.feature  |   62 +
 rspec-core/features/configuration/profile.feature  |  220 +++
 .../configuration/read_options_from_file.feature   |   95 +
 .../run_all_when_everything_filtered.feature       |   78 +
 .../zero_monkey_patching_mode.feature              |  106 +
 rspec-core/features/core_standalone.feature        |   23 +
 .../features/example_groups/aliasing.feature       |   48 +
 .../example_groups/basic_structure.feature         |   55 +
 .../features/example_groups/shared_context.feature |  112 ++
 .../example_groups/shared_examples.feature         |  295 +++
 .../configure_expectation_framework.feature        |  171 ++
 .../features/filtering/exclusion_filters.feature   |  135 ++
 .../features/filtering/if_and_unless.feature       |  165 ++
 .../features/filtering/inclusion_filters.feature   |  101 +
 .../formatters/configurable_colors.feature         |   32 +
 .../features/formatters/custom_formatter.feature   |   37 +
 .../features/formatters/json_formatter.feature     |   30 +
 .../helper_methods/arbitrary_methods.feature       |   40 +
 rspec-core/features/helper_methods/let.feature     |   50 +
 rspec-core/features/helper_methods/modules.feature |  152 ++
 rspec-core/features/hooks/around_hooks.feature     |  372 ++++
 .../features/hooks/before_and_after_hooks.feature  |  434 +++++
 rspec-core/features/hooks/filtering.feature        |  246 +++
 .../features/metadata/current_example.feature      |   57 +
 .../features/metadata/described_class.feature      |   17 +
 rspec-core/features/metadata/user_defined.feature  |  100 +
 .../use_any_framework.feature                      |  106 +
 .../use_flexmock.feature                           |   94 +
 .../mock_framework_integration/use_mocha.feature   |   95 +
 .../mock_framework_integration/use_rr.feature      |   96 +
 .../mock_framework_integration/use_rspec.feature   |  113 ++
 .../pending_and_skipped_examples/README.md         |    3 +
 .../pending_examples.feature                       |   74 +
 .../skipped_examples.feature                       |  112 ++
 .../spec_files/arbitrary_file_suffix.feature       |   13 +
 .../step_definitions/additional_cli_steps.rb       |  126 ++
 .../step_definitions/core_standalone_steps.rb      |   12 +
 .../features/subject/explicit_subject.feature      |  187 ++
 .../features/subject/implicit_subject.feature      |   57 +
 .../features/subject/one_liner_syntax.feature      |   72 +
 rspec-core/features/support/env.rb                 |   21 +
 .../require_expect_syntax_in_aruba_specs.rb        |   29 +
 rspec-core/features/support/rubinius.rb            |    6 +
 rspec-core/lib/rspec/autorun.rb                    |    2 +
 rspec-core/lib/rspec/core.rb                       |  189 ++
 rspec-core/lib/rspec/core/backport_random.rb       |  339 ++++
 rspec-core/lib/rspec/core/backtrace_formatter.rb   |   66 +
 rspec-core/lib/rspec/core/configuration.rb         | 1678 ++++++++++++++++
 rspec-core/lib/rspec/core/configuration_options.rb |  180 ++
 rspec-core/lib/rspec/core/drb.rb                   |  111 ++
 rspec-core/lib/rspec/core/dsl.rb                   |   96 +
 rspec-core/lib/rspec/core/example.rb               |  538 ++++++
 rspec-core/lib/rspec/core/example_group.rb         |  767 ++++++++
 rspec-core/lib/rspec/core/filter_manager.rb        |  216 +++
 rspec-core/lib/rspec/core/flat_map.rb              |   18 +
 rspec-core/lib/rspec/core/formatters.rb            |  244 +++
 .../lib/rspec/core/formatters/base_formatter.rb    |   70 +
 .../rspec/core/formatters/base_text_formatter.rb   |   76 +
 .../lib/rspec/core/formatters/console_codes.rb     |   65 +
 .../rspec/core/formatters/deprecation_formatter.rb |  224 +++
 .../core/formatters/documentation_formatter.rb     |   74 +
 rspec-core/lib/rspec/core/formatters/helpers.rb    |   89 +
 .../lib/rspec/core/formatters/html_formatter.rb    |  154 ++
 .../lib/rspec/core/formatters/html_printer.rb      |  419 ++++
 .../lib/rspec/core/formatters/json_formatter.rb    |   94 +
 .../lib/rspec/core/formatters/profile_formatter.rb |   68 +
 .../rspec/core/formatters/progress_formatter.rb    |   28 +
 rspec-core/lib/rspec/core/formatters/protocol.rb   |  172 ++
 .../lib/rspec/core/formatters/snippet_extractor.rb |  111 ++
 rspec-core/lib/rspec/core/hooks.rb                 |  632 ++++++
 rspec-core/lib/rspec/core/memoized_helpers.rb      |  472 +++++
 rspec-core/lib/rspec/core/metadata.rb              |  476 +++++
 rspec-core/lib/rspec/core/metadata_filter.rb       |  222 +++
 .../lib/rspec/core/minitest_assertions_adapter.rb  |   31 +
 .../lib/rspec/core/mocking_adapters/flexmock.rb    |   31 +
 .../lib/rspec/core/mocking_adapters/mocha.rb       |   57 +
 rspec-core/lib/rspec/core/mocking_adapters/null.rb |   14 +
 rspec-core/lib/rspec/core/mocking_adapters/rr.rb   |   31 +
 .../lib/rspec/core/mocking_adapters/rspec.rb       |   32 +
 rspec-core/lib/rspec/core/notifications.rb         |  603 ++++++
 rspec-core/lib/rspec/core/option_parser.rb         |  228 +++
 rspec-core/lib/rspec/core/ordering.rb              |  155 ++
 rspec-core/lib/rspec/core/pending.rb               |  165 ++
 rspec-core/lib/rspec/core/project_initializer.rb   |   48 +
 .../lib/rspec/core/project_initializer/.rspec      |    2 +
 .../core/project_initializer/spec/spec_helper.rb   |   91 +
 rspec-core/lib/rspec/core/rake_task.rb             |  172 ++
 rspec-core/lib/rspec/core/reporter.rb              |  172 ++
 rspec-core/lib/rspec/core/ruby_project.rb          |   53 +
 rspec-core/lib/rspec/core/runner.rb                |  155 ++
 rspec-core/lib/rspec/core/sandbox.rb               |   37 +
 rspec-core/lib/rspec/core/shared_context.rb        |   55 +
 rspec-core/lib/rspec/core/shared_example_group.rb  |  208 ++
 .../lib/rspec/core/test_unit_assertions_adapter.rb |   30 +
 rspec-core/lib/rspec/core/version.rb               |    9 +
 rspec-core/lib/rspec/core/warnings.rb              |   40 +
 rspec-core/lib/rspec/core/world.rb                 |  167 ++
 rspec-core/maintenance-branch                      |    1 +
 rspec-core/rspec-core.gemspec                      |   53 +
 rspec-core/script/clone_all_rspec_repos            |   24 +
 rspec-core/script/console                          |    8 +
 rspec-core/script/functions.sh                     |  129 ++
 rspec-core/script/ignores                          |   72 +
 rspec-core/script/list_method_cache_busters.sh     |   23 +
 rspec-core/script/predicate_functions.sh           |   64 +
 .../script/prevent_runtime_method_cache_busters    |   15 +
 rspec-core/script/regen_fixtures.sh                |   39 +
 rspec-core/script/rspec_with_simplecov             |   42 +
 rspec-core/script/run_build                        |   28 +
 rspec-core/script/travis_functions.sh              |   69 +
 rspec-core/spec/integration/filtering_spec.rb      |  148 ++
 rspec-core/spec/integration/order_spec.rb          |  204 ++
 .../spec/rspec/core/backtrace_formatter_spec.rb    |  304 +++
 .../spec/rspec/core/configuration_options_spec.rb  |  426 ++++
 rspec-core/spec/rspec/core/configuration_spec.rb   | 2041 ++++++++++++++++++++
 rspec-core/spec/rspec/core/drb_spec.rb             |  277 +++
 rspec-core/spec/rspec/core/dsl_spec.rb             |  105 +
 .../rspec/core/example_execution_result_spec.rb    |  140 ++
 .../rspec/core/example_group_constants_spec.rb     |   15 +
 rspec-core/spec/rspec/core/example_group_spec.rb   | 1787 +++++++++++++++++
 rspec-core/spec/rspec/core/example_spec.rb         |  735 +++++++
 .../rspec/core/failed_example_notification_spec.rb |   23 +
 rspec-core/spec/rspec/core/filter_manager_spec.rb  |  350 ++++
 .../rspec/core/filterable_item_repository_spec.rb  |  202 ++
 .../core/formatters/base_text_formatter_spec.rb    |  230 +++
 .../rspec/core/formatters/console_codes_spec.rb    |   64 +
 .../core/formatters/deprecation_formatter_spec.rb  |  230 +++
 .../formatters/documentation_formatter_spec.rb     |  110 ++
 .../spec/rspec/core/formatters/helpers_spec.rb     |  103 +
 .../spec/rspec/core/formatters/html_formatted.html |  373 ++++
 .../rspec/core/formatters/html_formatter_spec.rb   |  113 ++
 .../rspec/core/formatters/json_formatter_spec.rb   |  182 ++
 .../core/formatters/profile_formatter_spec.rb      |   98 +
 .../core/formatters/progress_formatter_spec.rb     |   54 +
 .../core/formatters/snippet_extractor_spec.rb      |   25 +
 rspec-core/spec/rspec/core/formatters_spec.rb      |  159 ++
 rspec-core/spec/rspec/core/hooks_filtering_spec.rb |  284 +++
 rspec-core/spec/rspec/core/hooks_spec.rb           |  429 ++++
 .../spec/rspec/core/memoized_helpers_spec.rb       |  535 +++++
 rspec-core/spec/rspec/core/metadata_filter_spec.rb |  175 ++
 rspec-core/spec/rspec/core/metadata_spec.rb        |  740 +++++++
 rspec-core/spec/rspec/core/notifications_spec.rb   |  104 +
 rspec-core/spec/rspec/core/option_parser_spec.rb   |  281 +++
 rspec-core/spec/rspec/core/ordering_spec.rb        |  100 +
 rspec-core/spec/rspec/core/pending_example_spec.rb |  221 +++
 rspec-core/spec/rspec/core/pending_spec.rb         |    6 +
 .../spec/rspec/core/project_initializer_spec.rb    |  122 ++
 rspec-core/spec/rspec/core/rake_task_spec.rb       |  401 ++++
 rspec-core/spec/rspec/core/random_spec.rb          |   45 +
 rspec-core/spec/rspec/core/reporter_spec.rb        |  209 ++
 rspec-core/spec/rspec/core/resources/a_bar.rb      |    0
 rspec-core/spec/rspec/core/resources/a_foo.rb      |    0
 rspec-core/spec/rspec/core/resources/a_spec.rb     |    1 +
 .../spec/rspec/core/resources/acceptance/bar.rb    |    0
 .../rspec/core/resources/acceptance/foo_spec.rb    |    0
 .../core/resources/custom_example_group_runner.rb  |   14 +
 .../spec/rspec/core/resources/formatter_specs.rb   |   58 +
 .../spec/rspec/core/resources/utf8_encoded.rb      |    9 +
 rspec-core/spec/rspec/core/rspec_matchers_spec.rb  |   43 +
 rspec-core/spec/rspec/core/ruby_project_spec.rb    |   51 +
 rspec-core/spec/rspec/core/runner_spec.rb          |  273 +++
 rspec-core/spec/rspec/core/shared_context_spec.rb  |  100 +
 .../spec/rspec/core/shared_example_group_spec.rb   |  353 ++++
 rspec-core/spec/rspec/core/suite_hooks_spec.rb     |  112 ++
 rspec-core/spec/rspec/core/warnings_spec.rb        |   70 +
 rspec-core/spec/rspec/core/world_spec.rb           |  140 ++
 rspec-core/spec/rspec/core_spec.rb                 |  208 ++
 rspec-core/spec/spec_helper.rb                     |   74 +
 rspec-core/spec/support/aruba_support.rb           |   60 +
 rspec-core/spec/support/config_options_helper.rb   |   13 +
 rspec-core/spec/support/fake_minitest/minitest.rb  |    0
 .../fake_minitest/minitest/minitest_assertions.rb  |    4 +
 .../support/fake_minitest/test/unit/assertions.rb  |    6 +
 rspec-core/spec/support/formatter_support.rb       |  282 +++
 rspec-core/spec/support/helper_methods.rb          |   26 +
 rspec-core/spec/support/isolated_home_directory.rb |   16 +
 rspec-core/spec/support/matchers.rb                |  114 ++
 .../spec/support/mathn_integration_support.rb      |   25 +
 rspec-core/spec/support/runner_support.rb          |   16 +
 rspec-core/spec/support/sandboxing.rb              |   21 +
 rspec-core/spec/support/shared_example_groups.rb   |   47 +
 rspec-core/spec/support/spec_files.rb              |   44 +
 rspec-expectations/.document                       |    5 +
 rspec-expectations/.gitignore                      |   17 +
 rspec-expectations/.rspec                          |    2 +
 rspec-expectations/.rubocop.yml                    |    5 +
 rspec-expectations/.rubocop_rspec_base.yml         |  130 ++
 rspec-expectations/.travis.yml                     |   37 +
 rspec-expectations/.yardopts                       |    6 +
 rspec-expectations/Changelog.md                    |  880 +++++++++
 rspec-expectations/DEV-README.md                   |   28 +
 rspec-expectations/Gemfile                         |   35 +
 rspec-expectations/Gemfile-custom.sample           |   19 +
 rspec-expectations/Guardfile                       |    6 +
 License.txt => rspec-expectations/License.txt      |    2 +-
 rspec-expectations/README.md                       |  289 +++
 rspec-expectations/Rakefile                        |   78 +
 rspec-expectations/Should.md                       |  168 ++
 rspec-expectations/appveyor.yml                    |   34 +
 .../2.x_vs_3.x_matcher_dsl_implementation.rb       |  253 +++
 .../benchmarks/autoload_v_require.rb               |   25 +
 rspec-expectations/benchmarks/cloning_matchers.rb  |   19 +
 .../default_messages_as_methods_v_blocks.rb        |   27 +
 rspec-expectations/benchmarks/example_spec.rb      |    9 +
 .../benchmarks/include_v_superclass.rb             |   39 +
 .../match_array/failing_with_distinct_items.rb     |  147 ++
 .../match_array/failing_with_duplicate_items.rb    |  122 ++
 .../match_array/passing_with_distinct_items.rb     |  154 ++
 .../match_array/passing_with_duplicate_items.rb    |  132 ++
 .../rubyprof/passing_with_distinct_items.rb        |    9 +
 .../benchmarks/matcher_dsl_vs_classes.rb           |  180 ++
 rspec-expectations/benchmarks/method_to_proc.rb    |   72 +
 .../benchmarks/output_stringio_vs_tempfile.rb      |   31 +
 .../benchmarks/set_vs_array_include.rb             |   68 +
 rspec-expectations/cucumber.yml                    |   10 +
 rspec-expectations/features/.nav                   |   41 +
 rspec-expectations/features/README.md              |   49 +
 .../features/built_in_matchers/README.md           |  137 ++
 .../features/built_in_matchers/all.feature         |   60 +
 .../features/built_in_matchers/be.feature          |  175 ++
 .../features/built_in_matchers/be_within.feature   |   48 +
 .../features/built_in_matchers/change.feature      |   66 +
 .../features/built_in_matchers/comparisons.feature |   96 +
 .../built_in_matchers/contain_exactly.feature      |   64 +
 .../features/built_in_matchers/cover.feature       |   47 +
 .../features/built_in_matchers/end_with.feature    |   48 +
 .../features/built_in_matchers/equality.feature    |  135 ++
 .../features/built_in_matchers/exist.feature       |   44 +
 .../built_in_matchers/have_attributes.feature      |   47 +
 .../features/built_in_matchers/include.feature     |  123 ++
 .../features/built_in_matchers/match.feature       |   49 +
 .../features/built_in_matchers/output.feature      |  131 ++
 .../features/built_in_matchers/predicates.feature  |  181 ++
 .../features/built_in_matchers/raise_error.feature |  144 ++
 .../features/built_in_matchers/respond_to.feature  |   83 +
 .../features/built_in_matchers/satisfy.feature     |   32 +
 .../features/built_in_matchers/start_with.feature  |   48 +
 .../built_in_matchers/throw_symbol.feature         |   90 +
 .../features/built_in_matchers/types.feature       |  116 ++
 .../features/built_in_matchers/yield.feature       |  156 ++
 .../features/composing_matchers.feature            |  246 +++
 .../features/compound_expectations.feature         |   52 +
 .../custom_matchers/access_running_example.feature |   48 +
 .../custom_matchers/define_block_matcher.feature   |   44 +
 .../define_diffable_matcher.feature                |   29 +
 .../custom_matchers/define_matcher.feature         |  337 ++++
 .../define_matcher_outside_rspec.feature           |   32 +
 .../define_matcher_with_fluent_interface.feature   |   70 +
 .../features/customized_message.feature            |   39 +
 .../features/define_negated_matcher.feature        |   29 +
 rspec-expectations/features/diffing.feature        |   85 +
 .../features/implicit_docstrings.feature           |   51 +
 .../step_definitions/additional_cli_steps.rb       |   22 +
 .../features/support/disallow_certain_apis.rb      |   34 +
 rspec-expectations/features/support/env.rb         |   21 +
 rspec-expectations/features/support/rubinius.rb    |    6 +
 .../features/syntax_configuration.feature          |   92 +
 .../features/test_frameworks/minitest.feature      |   44 +
 rspec-expectations/lib/rspec/expectations.rb       |   69 +
 .../lib/rspec/expectations/configuration.rb        |  147 ++
 .../lib/rspec/expectations/expectation_target.rb   |  119 ++
 .../lib/rspec/expectations/fail_with.rb            |   33 +
 .../lib/rspec/expectations/handler.rb              |  170 ++
 .../lib/rspec/expectations/minitest_integration.rb |   18 +
 .../lib/rspec/expectations/syntax.rb               |  132 ++
 .../lib/rspec/expectations/version.rb              |    8 +
 rspec-expectations/lib/rspec/matchers.rb           |  955 +++++++++
 .../lib/rspec/matchers/aliased_matcher.rb          |  116 ++
 rspec-expectations/lib/rspec/matchers/built_in.rb  |   52 +
 .../lib/rspec/matchers/built_in/all.rb             |   85 +
 .../lib/rspec/matchers/built_in/base_matcher.rb    |  132 ++
 .../lib/rspec/matchers/built_in/be.rb              |  273 +++
 .../lib/rspec/matchers/built_in/be_between.rb      |   77 +
 .../lib/rspec/matchers/built_in/be_instance_of.rb  |   22 +
 .../lib/rspec/matchers/built_in/be_kind_of.rb      |   16 +
 .../lib/rspec/matchers/built_in/be_within.rb       |   72 +
 .../lib/rspec/matchers/built_in/change.rb          |  337 ++++
 .../lib/rspec/matchers/built_in/compound.rb        |  293 +++
 .../lib/rspec/matchers/built_in/contain_exactly.rb |  249 +++
 .../lib/rspec/matchers/built_in/cover.rb           |   24 +
 .../lib/rspec/matchers/built_in/eq.rb              |   75 +
 .../lib/rspec/matchers/built_in/eql.rb             |   34 +
 .../lib/rspec/matchers/built_in/equal.rb           |   81 +
 .../lib/rspec/matchers/built_in/exist.rb           |   86 +
 .../lib/rspec/matchers/built_in/has.rb             |  101 +
 .../lib/rspec/matchers/built_in/have_attributes.rb |  113 ++
 .../lib/rspec/matchers/built_in/include.rb         |  105 +
 .../lib/rspec/matchers/built_in/match.rb           |   29 +
 .../lib/rspec/matchers/built_in/operators.rb       |  119 ++
 .../lib/rspec/matchers/built_in/output.rb          |  193 ++
 .../lib/rspec/matchers/built_in/raise_error.rb     |  174 ++
 .../lib/rspec/matchers/built_in/respond_to.rb      |   91 +
 .../lib/rspec/matchers/built_in/satisfy.rb         |   39 +
 .../rspec/matchers/built_in/start_or_end_with.rb   |   92 +
 .../lib/rspec/matchers/built_in/throw_symbol.rb    |  132 ++
 .../lib/rspec/matchers/built_in/yield.rb           |  416 ++++
 .../lib/rspec/matchers/composable.rb               |  183 ++
 rspec-expectations/lib/rspec/matchers/dsl.rb       |  440 +++++
 .../rspec/matchers/expecteds_for_multiple_diffs.rb |   79 +
 .../lib/rspec/matchers/generated_descriptions.rb   |   42 +
 .../lib/rspec/matchers/matcher_delegator.rb        |   33 +
 .../lib/rspec/matchers/matcher_protocol.rb         |   99 +
 rspec-expectations/lib/rspec/matchers/pretty.rb    |   77 +
 rspec-expectations/maintenance-branch              |    1 +
 rspec-expectations/rspec-expectations.gemspec      |   46 +
 rspec-expectations/script/clone_all_rspec_repos    |   24 +
 rspec-expectations/script/functions.sh             |  129 ++
 rspec-expectations/script/predicate_functions.sh   |   64 +
 rspec-expectations/script/run_build                |   28 +
 rspec-expectations/script/travis_functions.sh      |   69 +
 .../spec/rspec/expectations/configuration_spec.rb  |  226 +++
 .../rspec/expectations/expectation_target_spec.rb  |  147 ++
 .../rspec/expectations/extensions/kernel_spec.rb   |   69 +
 .../spec/rspec/expectations/fail_with_spec.rb      |   73 +
 .../spec/rspec/expectations/handler_spec.rb        |  200 ++
 .../expectations/minitest_integration_spec.rb      |   25 +
 .../spec/rspec/expectations/syntax_spec.rb         |   93 +
 rspec-expectations/spec/rspec/expectations_spec.rb |   15 +
 .../spec/rspec/matchers/aliased_matcher_spec.rb    |  113 ++
 .../spec/rspec/matchers/aliases_spec.rb            |  455 +++++
 .../spec/rspec/matchers/built_in/all_spec.rb       |  212 ++
 .../rspec/matchers/built_in/base_matcher_spec.rb   |  140 ++
 .../rspec/matchers/built_in/be_between_spec.rb     |  157 ++
 .../rspec/matchers/built_in/be_instance_of_spec.rb |   61 +
 .../rspec/matchers/built_in/be_kind_of_spec.rb     |   39 +
 .../spec/rspec/matchers/built_in/be_spec.rb        |  691 +++++++
 .../spec/rspec/matchers/built_in/be_within_spec.rb |  139 ++
 .../spec/rspec/matchers/built_in/change_spec.rb    |  829 ++++++++
 .../spec/rspec/matchers/built_in/compound_spec.rb  |  854 ++++++++
 .../matchers/built_in/contain_exactly_spec.rb      |  556 ++++++
 .../spec/rspec/matchers/built_in/cover_spec.rb     |   67 +
 .../spec/rspec/matchers/built_in/eq_spec.rb        |  176 ++
 .../spec/rspec/matchers/built_in/eql_spec.rb       |   39 +
 .../spec/rspec/matchers/built_in/equal_spec.rb     |  130 ++
 .../spec/rspec/matchers/built_in/exist_spec.rb     |  139 ++
 .../spec/rspec/matchers/built_in/has_spec.rb       |  179 ++
 .../matchers/built_in/have_attributes_spec.rb      |  230 +++
 .../spec/rspec/matchers/built_in/include_spec.rb   |  587 ++++++
 .../spec/rspec/matchers/built_in/match_spec.rb     |  100 +
 .../spec/rspec/matchers/built_in/operators_spec.rb |  250 +++
 .../spec/rspec/matchers/built_in/output_spec.rb    |  193 ++
 .../rspec/matchers/built_in/raise_error_spec.rb    |  446 +++++
 .../rspec/matchers/built_in/respond_to_spec.rb     |  290 +++
 .../spec/rspec/matchers/built_in/satisfy_spec.rb   |   42 +
 .../matchers/built_in/start_and_end_with_spec.rb   |  415 ++++
 .../rspec/matchers/built_in/throw_symbol_spec.rb   |  133 ++
 .../spec/rspec/matchers/built_in/yield_spec.rb     |  648 +++++++
 .../spec/rspec/matchers/composable_spec.rb         |   77 +
 .../rspec/matchers/define_negated_matcher_spec.rb  |  199 ++
 .../rspec/matchers/description_generation_spec.rb  |  202 ++
 rspec-expectations/spec/rspec/matchers/dsl_spec.rb | 1102 +++++++++++
 .../matchers/expecteds_for_multiple_diffs_spec.rb  |  114 ++
 .../spec/rspec/matchers/legacy_spec.rb             |  104 +
 rspec-expectations/spec/rspec/matchers_spec.rb     |  108 ++
 rspec-expectations/spec/spec_helper.rb             |   94 +
 rspec-expectations/spec/support/matchers.rb        |   55 +
 rspec-expectations/spec/support/shared_examples.rb |  101 +
 rspec-mocks/.autotest                              |    7 +
 rspec-mocks/.document                              |    5 +
 rspec-mocks/.gitignore                             |   18 +
 rspec-mocks/.rspec                                 |    2 +
 rspec-mocks/.rubocop.yml                           |   17 +
 rspec-mocks/.rubocop_rspec_base.yml                |  130 ++
 rspec-mocks/.travis.yml                            |   37 +
 rspec-mocks/.yardopts                              |    6 +
 rspec-mocks/Changelog.md                           |  893 +++++++++
 rspec-mocks/DEV-README.md                          |   28 +
 rspec-mocks/Gemfile                                |   30 +
 rspec-mocks/Gemfile-custom.sample                  |   19 +
 rspec-mocks/Guardfile                              |    8 +
 License.txt => rspec-mocks/License.txt             |    2 +-
 rspec-mocks/README.md                              |  430 +++++
 rspec-mocks/Rakefile                               |   72 +
 rspec-mocks/appveyor.yml                           |   34 +
 rspec-mocks/benchmarks/boot_time.sh                |   31 +
 rspec-mocks/benchmarks/double_creation.rb          |   66 +
 rspec-mocks/benchmarks/each_value_v_values_each.rb |   58 +
 .../benchmarks/find_original_method_early.rb       |   64 +
 .../benchmarks/method_defined_at_any_visibility.rb |  101 +
 rspec-mocks/benchmarks/thread_safety.rb            |   24 +
 .../benchmarks/transfer_nested_constants.rb        |   77 +
 rspec-mocks/cucumber.yml                           |    2 +
 rspec-mocks/features/.nav                          |   43 +
 rspec-mocks/features/README.md                     |   76 +
 .../features/basics/allowing_messages.feature      |   35 +
 .../features/basics/expecting_messages.feature     |   73 +
 .../features/basics/null_object_doubles.feature    |   35 +
 .../features/basics/partial_test_doubles.feature   |   70 +
 rspec-mocks/features/basics/scope.feature          |   99 +
 rspec-mocks/features/basics/spies.feature          |  129 ++
 rspec-mocks/features/basics/test_doubles.feature   |   41 +
 .../features/configuring_responses/README.md       |   12 +
 .../block_implementation.feature                   |  131 ++
 .../calling_the_original_implementation.feature    |   52 +
 .../configuring_responses/raising_an_error.feature |   28 +
 .../returning_a_value.feature                      |   52 +
 .../configuring_responses/throwing.feature         |   36 +
 .../wrapping_the_original_implementation.feature   |   53 +
 .../configuring_responses/yielding.feature         |   76 +
 rspec-mocks/features/mutating_constants/README.md  |   78 +
 .../hide_defined_constant.feature                  |   64 +
 .../hide_undefined_constant.feature                |   22 +
 .../stub_defined_constant.feature                  |   77 +
 .../stub_undefined_constant.feature                |   50 +
 rspec-mocks/features/old_syntax/README.md          |   35 +
 .../features/old_syntax/any_instance.feature       |  105 +
 .../features/old_syntax/should_receive.feature     |   90 +
 rspec-mocks/features/old_syntax/stub.feature       |   51 +
 rspec-mocks/features/old_syntax/stub_chain.feature |   69 +
 rspec-mocks/features/old_syntax/unstub.feature     |   43 +
 .../features/outside_rspec/minitest.feature        |   80 +
 .../features/outside_rspec/standalone.feature      |   33 +
 rspec-mocks/features/setting_constraints/README.md |    6 +
 .../setting_constraints/matching_arguments.feature |   98 +
 .../setting_constraints/message_order.feature      |   63 +
 .../setting_constraints/receive_counts.feature     |  189 ++
 .../step_definitions/additional_cli_steps.rb       |   21 +
 .../features/support/disallow_certain_apis.rb      |   24 +
 rspec-mocks/features/support/env.rb                |   22 +
 rspec-mocks/features/support/rubinius.rb           |    6 +
 rspec-mocks/features/verifying_doubles/README.md   |   13 +
 .../verifying_doubles/class_doubles.feature        |   70 +
 .../verifying_doubles/dynamic_classes.feature      |  110 ++
 .../verifying_doubles/instance_doubles.feature     |  103 +
 .../verifying_doubles/object_doubles.feature       |   62 +
 .../verifying_doubles/partial_doubles.feature      |   34 +
 .../features/working_with_legacy_code/README.md    |    3 +
 .../working_with_legacy_code/any_instance.feature  |  115 ++
 .../message_chains.feature                         |   79 +
 rspec-mocks/lib/rspec/mocks.rb                     |  126 ++
 rspec-mocks/lib/rspec/mocks/any_instance.rb        |   10 +
 rspec-mocks/lib/rspec/mocks/any_instance/chain.rb  |  110 ++
 .../rspec/mocks/any_instance/expect_chain_chain.rb |   35 +
 .../rspec/mocks/any_instance/expectation_chain.rb  |   48 +
 .../lib/rspec/mocks/any_instance/message_chains.rb |   85 +
 rspec-mocks/lib/rspec/mocks/any_instance/proxy.rb  |  116 ++
 .../lib/rspec/mocks/any_instance/recorder.rb       |  267 +++
 .../lib/rspec/mocks/any_instance/stub_chain.rb     |   46 +
 .../rspec/mocks/any_instance/stub_chain_chain.rb   |   27 +
 .../lib/rspec/mocks/argument_list_matcher.rb       |  100 +
 rspec-mocks/lib/rspec/mocks/argument_matchers.rb   |  320 +++
 rspec-mocks/lib/rspec/mocks/configuration.rb       |  187 ++
 rspec-mocks/lib/rspec/mocks/error_generator.rb     |  310 +++
 rspec-mocks/lib/rspec/mocks/example_methods.rb     |  424 ++++
 .../lib/rspec/mocks/instance_method_stasher.rb     |  135 ++
 rspec-mocks/lib/rspec/mocks/marshal_extension.rb   |   41 +
 .../mocks/matchers/expectation_customization.rb    |   20 +
 .../lib/rspec/mocks/matchers/have_received.rb      |  119 ++
 rspec-mocks/lib/rspec/mocks/matchers/receive.rb    |  130 ++
 .../rspec/mocks/matchers/receive_message_chain.rb  |   80 +
 .../lib/rspec/mocks/matchers/receive_messages.rb   |   75 +
 rspec-mocks/lib/rspec/mocks/message_chain.rb       |   91 +
 rspec-mocks/lib/rspec/mocks/message_expectation.rb |  714 +++++++
 rspec-mocks/lib/rspec/mocks/method_double.rb       |  283 +++
 rspec-mocks/lib/rspec/mocks/method_reference.rb    |  155 ++
 rspec-mocks/lib/rspec/mocks/mutate_const.rb        |  335 ++++
 rspec-mocks/lib/rspec/mocks/object_reference.rb    |  149 ++
 rspec-mocks/lib/rspec/mocks/order_group.rb         |   81 +
 rspec-mocks/lib/rspec/mocks/proxy.rb               |  431 +++++
 rspec-mocks/lib/rspec/mocks/space.rb               |  221 +++
 rspec-mocks/lib/rspec/mocks/standalone.rb          |    3 +
 rspec-mocks/lib/rspec/mocks/syntax.rb              |  325 ++++
 rspec-mocks/lib/rspec/mocks/targets.rb             |   97 +
 rspec-mocks/lib/rspec/mocks/test_double.rb         |  135 ++
 rspec-mocks/lib/rspec/mocks/verifying_double.rb    |  134 ++
 .../rspec/mocks/verifying_message_expecation.rb    |   54 +
 rspec-mocks/lib/rspec/mocks/verifying_proxy.rb     |  173 ++
 rspec-mocks/lib/rspec/mocks/version.rb             |    9 +
 rspec-mocks/maintenance-branch                     |    1 +
 rspec-mocks/rspec-mocks.gemspec                    |   46 +
 rspec-mocks/script/clone_all_rspec_repos           |   24 +
 rspec-mocks/script/functions.sh                    |  129 ++
 rspec-mocks/script/ignores                         |   55 +
 rspec-mocks/script/list_method_cache_busters.sh    |   22 +
 rspec-mocks/script/predicate_functions.sh          |   64 +
 rspec-mocks/script/run_build                       |   28 +
 rspec-mocks/script/travis_functions.sh             |   69 +
 .../spec/rspec/mocks/and_call_original_spec.rb     |  267 +++
 rspec-mocks/spec/rspec/mocks/and_return_spec.rb    |   21 +
 .../spec/rspec/mocks/and_wrap_original_spec.rb     |   77 +
 rspec-mocks/spec/rspec/mocks/and_yield_spec.rb     |  161 ++
 .../mocks/any_instance/message_chains_spec.rb      |   39 +
 rspec-mocks/spec/rspec/mocks/any_instance_spec.rb  | 1242 ++++++++++++
 .../spec/rspec/mocks/argument_matchers_spec.rb     |  425 ++++
 .../rspec/mocks/array_including_matcher_spec.rb    |   62 +
 rspec-mocks/spec/rspec/mocks/at_least_spec.rb      |  147 ++
 rspec-mocks/spec/rspec/mocks/at_most_spec.rb       |  113 ++
 rspec-mocks/spec/rspec/mocks/before_all_spec.rb    |   75 +
 .../spec/rspec/mocks/block_return_value_spec.rb    |   68 +
 .../combining_implementation_instructions_spec.rb  |  200 ++
 rspec-mocks/spec/rspec/mocks/configuration_spec.rb |  189 ++
 rspec-mocks/spec/rspec/mocks/diffing_spec.rb       |  131 ++
 rspec-mocks/spec/rspec/mocks/double_spec.rb        |  830 ++++++++
 .../spec/rspec/mocks/error_generator_spec.rb       |   59 +
 .../spec/rspec/mocks/example_methods_spec.rb       |   38 +
 rspec-mocks/spec/rspec/mocks/expiration_spec.rb    |   90 +
 .../rspec/mocks/hash_excluding_matcher_spec.rb     |   65 +
 .../rspec/mocks/hash_including_matcher_spec.rb     |   98 +
 .../rspec/mocks/instance_method_stasher_spec.rb    |   72 +
 .../spec/rspec/mocks/marshal_extension_spec.rb     |   67 +
 .../rspec/mocks/matchers/have_received_spec.rb     |  513 +++++
 .../mocks/matchers/receive_message_chain_spec.rb   |  242 +++
 .../rspec/mocks/matchers/receive_messages_spec.rb  |  154 ++
 .../spec/rspec/mocks/matchers/receive_spec.rb      |  538 ++++++
 rspec-mocks/spec/rspec/mocks/methods_spec.rb       |   24 +
 .../rspec/mocks/mock_expectation_error_spec.rb     |   20 +
 rspec-mocks/spec/rspec/mocks/mock_ordering_spec.rb |  112 ++
 .../mocks/modifying_invoked_expectations_spec.rb   |   27 +
 .../spec/rspec/mocks/multiple_return_value_spec.rb |  130 ++
 rspec-mocks/spec/rspec/mocks/mutate_const_spec.rb  |  584 ++++++
 .../rspec/mocks/nil_expectation_warning_spec.rb    |   52 +
 .../spec/rspec/mocks/null_object_double_spec.rb    |  135 ++
 rspec-mocks/spec/rspec/mocks/once_counts_spec.rb   |   50 +
 rspec-mocks/spec/rspec/mocks/order_group_spec.rb   |   26 +
 .../spec/rspec/mocks/partial_double_spec.rb        |  415 ++++
 .../partial_double_using_mocks_directly_spec.rb    |   83 +
 .../spec/rspec/mocks/precise_counts_spec.rb        |   66 +
 rspec-mocks/spec/rspec/mocks/serialization_spec.rb |   89 +
 rspec-mocks/spec/rspec/mocks/should_syntax_spec.rb |  539 ++++++
 rspec-mocks/spec/rspec/mocks/space_spec.rb         |  242 +++
 rspec-mocks/spec/rspec/mocks/spy_spec.rb           |  127 ++
 rspec-mocks/spec/rspec/mocks/standalone_spec.rb    |   27 +
 rspec-mocks/spec/rspec/mocks/stash_spec.rb         |   43 +
 rspec-mocks/spec/rspec/mocks/stub_chain_spec.rb    |  166 ++
 .../spec/rspec/mocks/stub_implementation_spec.rb   |   98 +
 rspec-mocks/spec/rspec/mocks/stub_spec.rb          |  540 ++++++
 .../mocks/stubbed_message_expectations_spec.rb     |   56 +
 .../mocks/syntax_agnostic_message_matchers_spec.rb |   99 +
 rspec-mocks/spec/rspec/mocks/syntax_spec.rb        |    7 +
 rspec-mocks/spec/rspec/mocks/test_double_spec.rb   |   53 +
 rspec-mocks/spec/rspec/mocks/thrice_counts_spec.rb |   72 +
 rspec-mocks/spec/rspec/mocks/to_ary_spec.rb        |   52 +
 rspec-mocks/spec/rspec/mocks/twice_counts_spec.rb  |   64 +
 .../class_double_with_class_loaded_spec.rb         |  160 ++
 .../class_double_with_class_not_loaded_spec.rb     |   72 +
 .../mocks/verifying_doubles/construction_spec.rb   |  130 ++
 .../expected_arg_verification_spec.rb              |  128 ++
 .../instance_double_with_class_loaded_spec.rb      |  218 +++
 .../instance_double_with_class_not_loaded_spec.rb  |   71 +
 .../verifying_doubles/method_visibility_spec.rb    |  129 ++
 .../rspec/mocks/verifying_doubles/naming_spec.rb   |   83 +
 .../mocks/verifying_doubles/object_double_spec.rb  |  134 ++
 rspec-mocks/spec/rspec/mocks_spec.rb               |  206 ++
 rspec-mocks/spec/spec_helper.rb                    |  166 ++
 .../support/before_all_shared_example_group.rb     |   16 +
 rspec-mocks/spec/support/doubled_classes.rb        |   86 +
 rspec-mocks/spec/support/matchers.rb               |   15 +
 rspec-support/.gitignore                           |   21 +
 rspec-support/.rspec                               |    4 +
 rspec-support/.rubocop.yml                         |    1 +
 rspec-support/.rubocop_rspec_base.yml              |  130 ++
 rspec-support/.travis.yml                          |   37 +
 rspec-support/Changelog.md                         |  105 +
 rspec-support/Gemfile                              |   21 +
 License.txt => rspec-support/LICENSE.txt           |   16 +-
 rspec-support/README.md                            |   26 +
 rspec-support/Rakefile                             |   30 +
 rspec-support/appveyor.yml                         |   34 +
 rspec-support/benchmarks/caller.rb                 |   81 +
 .../benchmarks/caller_vs_caller_locations.rb       |   19 +
 .../benchmarks/skip_frames_for_caller_filter.rb    |   27 +
 rspec-support/lib/rspec/support.rb                 |   76 +
 rspec-support/lib/rspec/support/caller_filter.rb   |   83 +
 rspec-support/lib/rspec/support/differ.rb          |  215 +++
 rspec-support/lib/rspec/support/directory_maker.rb |   61 +
 rspec-support/lib/rspec/support/encoded_string.rb  |  148 ++
 rspec-support/lib/rspec/support/fuzzy_matcher.rb   |   48 +
 rspec-support/lib/rspec/support/hunk_generator.rb  |   47 +
 .../lib/rspec/support/matcher_definition.rb        |   42 +
 .../lib/rspec/support/method_signature_verifier.rb |  273 +++
 .../lib/rspec/support/recursive_const_methods.rb   |   76 +
 rspec-support/lib/rspec/support/ruby_features.rb   |  116 ++
 rspec-support/lib/rspec/support/spec.rb            |   76 +
 .../lib/rspec/support/spec/deprecation_helpers.rb  |   60 +
 .../lib/rspec/support/spec/formatting_support.rb   |    9 +
 .../lib/rspec/support/spec/in_sub_process.rb       |   47 +
 .../support/spec/prevent_load_time_warnings.rb     |   56 +
 rspec-support/lib/rspec/support/spec/shell_out.rb  |   69 +
 .../lib/rspec/support/spec/stderr_splitter.rb      |   63 +
 .../rspec/support/spec/with_isolated_directory.rb  |    9 +
 .../lib/rspec/support/spec/with_isolated_stderr.rb |   13 +
 rspec-support/lib/rspec/support/version.rb         |    7 +
 rspec-support/lib/rspec/support/version_checker.rb |   53 +
 rspec-support/lib/rspec/support/warnings.rb        |   39 +
 rspec-support/maintenance-branch                   |    1 +
 rspec-support/rspec-support.gemspec                |   34 +
 rspec-support/script/clone_all_rspec_repos         |   24 +
 rspec-support/script/functions.sh                  |  129 ++
 rspec-support/script/predicate_functions.sh        |   64 +
 rspec-support/script/run_build                     |   28 +
 rspec-support/script/travis_functions.sh           |   69 +
 .../spec/rspec/support/caller_filter_spec.rb       |   74 +
 rspec-support/spec/rspec/support/differ_spec.rb    |  366 ++++
 .../spec/rspec/support/directory_maker_spec.rb     |   60 +
 .../spec/rspec/support/encoded_string_spec.rb      |  255 +++
 .../spec/rspec/support/fuzzy_matcher_spec.rb       |  184 ++
 .../spec/rspec/support/matcher_definition_spec.rb  |   37 +
 .../support/method_signature_verifier_spec.rb      |  381 ++++
 .../rspec/support/recursive_const_methods_spec.rb  |   49 +
 .../spec/rspec/support/ruby_features_spec.rb       |   82 +
 .../spec/rspec/support/spec/in_sub_process_spec.rb |   48 +
 .../spec/prevent_load_time_warnings_spec.rb        |   10 +
 .../spec/rspec/support/spec/shell_out_spec.rb      |   44 +
 .../rspec/support/spec/stderr_splitter_spec.rb     |   92 +
 .../support/spec/with_isolated_std_err_spec.rb     |   21 +
 .../spec/rspec/support/version_checker_spec.rb     |   29 +
 rspec-support/spec/rspec/support/warnings_spec.rb  |   66 +
 rspec-support/spec/rspec/support_spec.rb           |  119 ++
 rspec-support/spec/spec_helper.rb                  |    2 +
 rspec/.document                                    |    2 +
 rspec/.gitignore                                   |   11 +
 rspec/Gemfile                                      |    7 +
 License.txt => rspec/License.txt                   |    0
 README.md => rspec/README.md                       |    4 +-
 rspec/Rakefile                                     |   25 +
 rspec/certs/rspec.pem                              |   34 +
 rspec/certs/samphippen.asc                         |   18 +
 {lib => rspec/lib}/rspec.rb                        |    0
 {lib => rspec/lib}/rspec/version.rb                |    2 +-
 rspec/rspec.gemspec                                |   40 +
 702 files changed, 89734 insertions(+), 120 deletions(-)

diff --git a/metadata.yml b/metadata.yml
deleted file mode 100644
index cff2f71..0000000
--- a/metadata.yml
+++ /dev/null
@@ -1,106 +0,0 @@
---- !ruby/object:Gem::Specification
-name: rspec
-version: !ruby/object:Gem::Version
-  prerelease: 
-  version: 2.14.1
-platform: ruby
-authors:
-- Steven Baker
-- David Chelimsky
-autorequire: 
-bindir: bin
-cert_chain: []
-date: 2013-07-11 00:00:00.000000000 Z
-dependencies:
-- !ruby/object:Gem::Dependency
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - ~>
-      - !ruby/object:Gem::Version
-        version: 2.14.0
-    none: false
-  prerelease: false
-  name: rspec-core
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - ~>
-      - !ruby/object:Gem::Version
-        version: 2.14.0
-    none: false
-  type: :runtime
-- !ruby/object:Gem::Dependency
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - ~>
-      - !ruby/object:Gem::Version
-        version: 2.14.0
-    none: false
-  prerelease: false
-  name: rspec-expectations
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - ~>
-      - !ruby/object:Gem::Version
-        version: 2.14.0
-    none: false
-  type: :runtime
-- !ruby/object:Gem::Dependency
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - ~>
-      - !ruby/object:Gem::Version
-        version: 2.14.0
-    none: false
-  prerelease: false
-  name: rspec-mocks
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - ~>
-      - !ruby/object:Gem::Version
-        version: 2.14.0
-    none: false
-  type: :runtime
-description: BDD for Ruby
-email: rspec-users at rubyforge.org
-executables: []
-extensions: []
-extra_rdoc_files:
-- README.md
-files:
-- lib/rspec.rb
-- lib/rspec/version.rb
-- License.txt
-- README.md
-homepage: http://github.com/rspec
-licenses:
-- MIT
-post_install_message: 
-rdoc_options:
-- --charset=UTF-8
-require_paths:
-- lib
-required_ruby_version: !ruby/object:Gem::Requirement
-  requirements:
-  - - ! '>='
-    - !ruby/object:Gem::Version
-      version: '0'
-      segments:
-      - 0
-      hash: -3009817662952132849
-  none: false
-required_rubygems_version: !ruby/object:Gem::Requirement
-  requirements:
-  - - ! '>='
-    - !ruby/object:Gem::Version
-      version: '0'
-      segments:
-      - 0
-      hash: -3009817662952132849
-  none: false
-requirements: []
-rubyforge_project: rspec
-rubygems_version: 1.8.24
-signing_key: 
-specification_version: 3
-summary: rspec-2.14.1
-test_files: []
diff --git a/rspec-core/.document b/rspec-core/.document
new file mode 100644
index 0000000..050e204
--- /dev/null
+++ b/rspec-core/.document
@@ -0,0 +1,5 @@
+lib/**/*.rb
+-
+README.md
+License.txt
+Changelog.md
diff --git a/rspec-core/.gitignore b/rspec-core/.gitignore
new file mode 100644
index 0000000..2d9a1ea
--- /dev/null
+++ b/rspec-core/.gitignore
@@ -0,0 +1,21 @@
+.rvmrc
+*.sw?
+.DS_Store
+coverage*
+doc
+rdoc
+pkg
+tmp
+tags
+rerun.txt
+Gemfile.lock
+.bundle
+*.rbc
+bin
+.rbx
+.yardoc
+vendor
+Gemfile-custom
+.idea
+bundle
+.rspec-local
diff --git a/rspec-core/.rspec b/rspec-core/.rspec
new file mode 100644
index 0000000..eb8599d
--- /dev/null
+++ b/rspec-core/.rspec
@@ -0,0 +1,3 @@
+--order rand
+--warnings
+--require spec_helper
diff --git a/rspec-core/.rubocop.yml b/rspec-core/.rubocop.yml
new file mode 100644
index 0000000..368bdfb
--- /dev/null
+++ b/rspec-core/.rubocop.yml
@@ -0,0 +1,53 @@
+inherit_from: .rubocop_rspec_base.yml
+
+AllCops:
+  Exclude:
+    # This code was taken from the backports gem. We don't want to mess with it.
+    - lib/rspec/core/backport_random.rb
+
+# This should go down over time.
+ClassLength:
+  Max: 330
+
+# This should go down over time.
+LineLength:
+  Max: 130
+
+Lint/HandleExceptions:
+  Exclude:
+    - lib/rspec/core/example.rb
+    - lib/rspec/core/mocking_adapters/mocha.rb
+    - lib/rspec/core/runner.rb
+    - lib/rspec/core/test_unit_assertions_adapter.rb
+
+Lint/LiteralInInterpolation:
+  Enabled: false
+
+# This should go down over time.
+MethodLength:
+  Max: 155
+
+# Exclude the default spec_helper to make it easier to uncomment out
+# default settings (for both users and the Cucumber suite).
+Style/BlockComments:
+  Exclude:
+    - lib/rspec/core/project_initializer/spec/spec_helper.rb
+
+# Not sure what to do with this rule yet.
+Style/ClassAndModuleChildren:
+  Exclude:
+    - lib/rspec/core/formatters.rb
+    - lib/rspec/core/notifications.rb
+    - lib/rspec/core/option_parser.rb
+    - lib/rspec/core/reporter.rb
+
+# This should go down over time.
+Style/CyclomaticComplexity:
+  Max: 12
+
+Style/RaiseArgs:
+  Exclude:
+    - lib/rspec/core/configuration.rb
+    - lib/rspec/core/hooks.rb
+    - lib/rspec/core/option_parser.rb
+    - lib/rspec/core/pending.rb
diff --git a/rspec-core/.rubocop_rspec_base.yml b/rspec-core/.rubocop_rspec_base.yml
new file mode 100644
index 0000000..f7bea1c
--- /dev/null
+++ b/rspec-core/.rubocop_rspec_base.yml
@@ -0,0 +1,130 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# This file contains defaults for RSpec projects. Individual projects
+# can customize by inheriting this file and overriding particular settings.
+
+AccessModifierIndentation:
+  EnforcedStyle: outdent
+
+# "Use alias_method instead of alias"
+# We're fine with `alias`.
+Alias:
+  Enabled: false
+
+AlignParameters:
+  EnforcedStyle: with_first_parameter
+
+# "Avoid the use of the case equality operator ==="
+# We prefer using `Class#===` over `Object#is_a?` because `Class#===`
+# is less likely to be monkey patched than `is_a?` on a user object.
+CaseEquality:
+  Enabled: false
+
+# Warns when the class is excessively long.
+ClassLength:
+  Max: 100
+
+CollectionMethods:
+  PreferredMethods:
+    reduce: 'inject'
+
+# Over time we'd like to get this down, but this is what we're at now.
+CyclomaticComplexity:
+  Max: 10
+
+# We use YARD to enforce documentation. It works better than rubocop's
+# enforcement...rubocop complains about the places we re-open
+# `RSpec::Expectations` and `RSpec::Matchers` w/o having doc commments.
+Documentation:
+  Enabled: false
+
+# We still support 1.8.7 which requires trailing dots
+DotPosition:
+  EnforcedStyle: trailing
+
+DoubleNegation:
+  Enabled: false
+
+# each_with_object is unavailable on 1.8.7 so we have to disable this one.
+EachWithObject:
+  Enabled: false
+
+Encoding:
+  EnforcedStyle: when_needed
+
+FormatString:
+  EnforcedStyle: percent
+
+# As long as we support ruby 1.8.7 we have to use hash rockets.
+HashSyntax:
+  EnforcedStyle: hash_rockets
+
+# We can't use the new lambda syntax, since we still support 1.8.7.
+Lambda:
+  Enabled: false
+
+# Over time we'd like to get this down, but this is what we're at now.
+LineLength:
+  Max: 100
+
+# Over time we'd like to get this down, but this is what we're at now.
+MethodLength:
+  Max: 15
+
+# Who cares what we call the argument for binary operator methods?
+OpMethod:
+  Enabled: false
+
+PercentLiteralDelimiters:
+  PreferredDelimiters:
+    '%':  ()      # double-quoted string
+    '%i': '[]'    # array of symbols
+    '%q': ()      # single-quoted string
+    '%Q': ()      # double-quoted string
+    '%r': '{}'    # regular expression pattern
+    '%s': ()      # a symbol
+    '%w': '[]'    # array of single-quoted strings
+    '%W': '[]'    # array of double-quoted strings
+    '%x': ()      # a shell command as a string
+
+# We have too many special cases where we allow generator methods or prefer a
+# prefixed predicate due to it's improved readability.
+PredicateName:
+  Enabled: false
+
+# On 1.8 `proc` is `lambda`, so we use `Proc.new` to ensure we get real procs on all supported versions.
+# http://batsov.com/articles/2014/02/04/the-elements-of-style-in-ruby-number-12-proc-vs-proc-dot-new/
+Proc:
+  Enabled: false
+
+RedundantReturn:
+  AllowMultipleReturnValues: true
+
+# We have to rescue Exception in the `raise_error` matcher for it to work properly.
+RescueException:
+  Enabled: false
+
+# We haven't adopted the `fail` to signal exceptions vs `raise` for re-raises convention.
+SignalException:
+  Enabled: false
+
+# We've tended to use no space, so it's less of a change to stick with that.
+SpaceAroundEqualsInParameterDefault:
+  EnforcedStyle: no_space
+
+# We don't care about single vs double qoutes.
+StringLiterals:
+  Enabled: false
+
+# This rule favors constant names from the English standard library which we don't load.
+Style/SpecialGlobalVars:
+  Enabled: false
+
+Style/TrailingComma:
+  Enabled: false
+
+TrivialAccessors:
+  AllowDSLWriters: true
+  AllowPredicates: true
+  ExactNameMatch: true
diff --git a/rspec-core/.travis.yml b/rspec-core/.travis.yml
new file mode 100644
index 0000000..ea4f1b0
--- /dev/null
+++ b/rspec-core/.travis.yml
@@ -0,0 +1,37 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+language: ruby
+sudo: false
+cache:
+  directories:
+    - ../bundle
+before_install:
+  - "script/clone_all_rspec_repos"
+  # Downgrade bundler to work around https://github.com/bundler/bundler/issues/3004
+  # Note this doesn't work on JRUBY 2.0.0 mode so we don't do it
+  - if [ -z "$JRUBY_OPTS" ]; then gem install bundler -v=1.5.3 && alias bundle="bundle _1.5.3_"; fi
+bundler_args: "--binstubs --standalone --without documentation --path ../bundle"
+script: "script/run_build"
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - 2.1
+  - 2.2
+  - ruby-head
+  - ree
+  - jruby-18mode
+  - jruby
+  - jruby-head
+  - rbx
+matrix:
+  include:
+    - rvm: jruby
+      env: JRUBY_OPTS='--2.0'
+  allow_failures:
+    - rvm: jruby-head
+    - rvm: ruby-head
+    - rvm: rbx
+  fast_finish: true
diff --git a/rspec-core/.yardopts b/rspec-core/.yardopts
new file mode 100644
index 0000000..0ab6943
--- /dev/null
+++ b/rspec-core/.yardopts
@@ -0,0 +1,8 @@
+--exclude features
+--no-private
+--markup markdown
+--default-return void
+-
+Filtering.md
+Changelog.md
+License.txt
diff --git a/rspec-core/Changelog.md b/rspec-core/Changelog.md
new file mode 100644
index 0000000..2e26b72
--- /dev/null
+++ b/rspec-core/Changelog.md
@@ -0,0 +1,1743 @@
+### 3.2.2 / 2015-03-11
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.1...v3.2.2)
+
+Bug Fixes:
+
+* Fix regression in 3.2.0 that allowed tag-filtered examples to
+  run even if there was a location filter applied to the spec
+  file that was intended to limit the file to other examples.
+  (#1894, Myron Marston)
+
+### 3.2.1 / 2015-02-23
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.2.0...v3.2.1)
+
+Bug Fixes:
+
+* Notify start-of-run seed _before_ `start` notification rather than
+  _after_ so that formatters like Fuubar work properly. (Samuel Esposito, #1882)
+
+### 3.2.0 / 2015-02-03
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.7...v3.2.0)
+
+Enhancements:
+
+* Improve the `inspect` output of example groups. (Mike Dalton, #1687)
+* When rake task fails, only output the command if `verbose` flag is
+  set. (Ben Snape, #1704)
+* Add `RSpec.clear_examples` as a clear way to reset examples in between
+  spec runs, whilst retaining user configuration.  (Alexey Fedorov, #1706)
+* Reduce string allocations when defining and running examples by 70%
+  and 50% respectively. (Myron Marston, #1738)
+* Removed dependency on pathname from stdlib. (Sam Phippen, #1703)
+* Improve the message presented when a user hits Ctrl-C.
+  (Alex Chaffee #1717, #1742)
+* Improve shared example group inclusion backtrace displayed
+  in failed example output so that it works for all methods
+  of including shared example groups and shows all inclusion
+  locations. (Myron Marston, #1763)
+* Issue seed notification at start (as well as the end) of the reporter
+  run. (Arlandis Word, #1761)
+* Improve the documentation of around hooks. (Jim Kingdon, #1772)
+* Support prepending of modules into example groups from config and allow
+  filtering based on metadata. (Arlandis Word, #1806)
+* Emit warnings when `:suite` hooks are registered on an example group
+  (where it has always been ignored) or are registered with metadata
+  (which has always been ignored). (Myron Marston, #1805)
+* Provide a friendly error message when users call RSpec example group
+  APIs (e.g. `context`, `describe`, `it`, `let`, `before`, etc) from
+  within an example where those APIs are unavailable. (Myron Marston, #1819)
+* Provide a friendly error message when users call RSpec example
+  APIs (e.g. `expect`, `double`, `stub_const`, etc) from
+  within an example group where those APIs are unavailable.
+  (Myron Marston, #1819)
+* Add new `RSpec::Core::Sandbox.sandboxed { }` API that facilitates
+  testing RSpec with RSpec, allowing you to define example groups
+  and example from within an example without affecting the global
+  `RSpec.world` state. (Tyler Ball, 1808)
+* Apply line-number filters only to the files they are scoped to,
+  allowing you to mix filtered and unfiltered files. (Myron Marston, #1839)
+* When dumping pending examples, include the failure details so that you
+  don't have to un-pend the example to see it. (Myron Marston, #1844)
+* Make `-I` option support multiple values when separated by
+  `File::PATH_SEPARATOR`, such as `rspec -I foo:bar`. This matches
+  the behavior of Ruby's `-I` option. (Fumiaki Matsushima, #1855).
+
+Bug Fixes:
+
+* When assigning generated example descriptions, surface errors
+  raised by `matcher.description` in the example description.
+  (Myron Marston, #1771)
+* Don't consider expectations from `after` hooks when generating
+  example descriptions. (Myron Marston, #1771)
+* Don't apply metadata-filtered config hooks to examples in groups
+  with matching metadata when those examples override the parent
+  metadata value to not match. (Myron Marston, #1796)
+* Fix `config.expect_with :minitest` so that `skip` uses RSpec's
+  implementation rather than Minitest's. (Jonathan Rochkind, #1822)
+* Fix `NameError` caused when duplicate example group aliases are defined and
+  the DSL is not globally exposed. (Aaron Kromer, #1825)
+* When a shared example defined in an external file fails, use the host
+  example group (from a loaded spec file) for the re-run command to
+  ensure the command will actually work. (Myron Marston, #1835)
+* Fix location filtering to work properly for examples defined in
+  a nested example group within a shared example group defined in
+  an external file. (Bradley Schaefer, Xavier Shay, Myron Marston, #1837)
+* When a pending example fails (as expected) due to a mock expectation,
+  set `RSpec::Core::Example::ExecutionResult#pending_exception` --
+  previously it was not being set but should have been. (Myron Marston, #1844)
+* Fix rake task to work when `rspec-core` is installed in a directory
+  containing a space. (Guido Günther, #1845)
+* Fix regression in 3.1 that caused `describe Regexp` to raise errors.
+  (Durran Jordan, #1853)
+* Fix regression in 3.x that caused the profile information to be printed
+  after the summary. (Max Lincoln, #1857)
+* Apply `--seed` before loading `--require` files so that required files
+  can access the provided seed. (Myron Marston, #1745)
+* Handle `RSpec::Core::Formatters::DeprecationFormatter::FileStream` being
+  reopened with an IO stream, which sometimes happens with spring.
+  (Kevin Mook, #1757)
+
+### 3.1.7 / 2014-10-11
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.6...v3.1.7)
+
+Bug Fixes:
+
+* Fix `Metadata.relative_path` so that for a current directory of
+  `/foo/bar`, `/foo/bar_1` is not wrongly converted to `._1`.
+  (Akos Vandra, #1730)
+* Prevent constant lookup mistakenly finding `RSpec::ExampleGroups` generated
+  constants on 1.9.2 by appending a trailing `_` to the generated names.
+  (Jon Rowe, #1737)
+* Fix bug in `:pending` metadata. If it got set in any way besides passing
+  it as part of the metadata literal passed to `it` (such as by using
+  `define_derived_metadata`), it did not have the desired effect,
+  instead marking the example as `:passed`. (Myron Marston, #1739)
+
+### 3.1.6 / 2014-10-08
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.5...v3.1.6)
+
+Bug Fixes:
+
+* Fix regression in rake task pattern handling, that prevented patterns
+  that were relative from the current directory rather than from `spec`
+  from working properly. (Myron Marston, #1734)
+* Prevent rake task from generating duplicate load path entries.
+  (Myron Marston, #1735)
+
+### 3.1.5 / 2014-09-29
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.4...v3.1.5)
+
+Bug Fixes:
+
+* Fix issue with the rake task incorrectly escaping strings on Windows.
+  (Jon Rowe #1718)
+* Support absolute path patterns. While this wasn't officially supported
+  previously, setting `rake_task.pattern` to an absolute path pattern in
+  RSpec 3.0 and before worked since it delegated to `FileList` internally
+  (but now just forwards the pattern on to the `rspec` command).
+  (Myron Marston, #1726)
+
+### 3.1.4 / 2014-09-18
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.3...v3.1.4)
+
+Bug Fixes:
+
+* Fix implicit `subject` when using `describe false` or `describe nil`
+  so that it returns the provided primitive rather than the string
+  representation. (Myron Marston, #1710)
+* Fix backtrace filtering to allow code in subdirectories of your
+  current working directory (such as vendor/bundle/...) to be filtered
+  from backtraces. (Myron Marston, #1708)
+
+### 3.1.3 / 2014-09-15
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.2...v3.1.3)
+
+Bug Fixes:
+
+* Fix yet another regression in rake task pattern handling, to allow
+  `task.pattern = FileList["..."]` to work. That was never intended
+  to be supported but accidentally worked in 3.0 and earlier.
+  (Myron Marston, #1701)
+* Fix pattern handling so that files are normalized to absolute paths
+  before subtracting the `--exclude-pattern` matched files from the
+  `--pattern` matched files so that it still works even if the patterns
+  are in slightly different forms (e.g. one starting with `./`).
+  (Christian Nelson, #1698)
+
+### 3.1.2 / 2014-09-08
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.1...v3.1.2)
+
+Bug Fixes:
+
+* Fix another regression in rake task pattern handling, so that patterns
+  that start with `./` still work. (Christian Nelson, #1696)
+
+### 3.1.1 / 2014-09-05
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.0...v3.1.1)
+
+Bug Fixes:
+
+* Fix a regression in rake task pattern handling, so that `rake_task.pattern = array`
+  works again. While we never intended to support array values (or even knew that worked!),
+  the implementation from 3.0 and earlier used `FileList` internally, which allows arrays.
+  The fix restores the old behavior. (Myron Marston, #1694)
+
+### 3.1.0 / 2014-09-04
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.4...v3.1.0)
+
+Enhancements:
+
+* Update files generated by `rspec --init` so that warnings are enabled
+  in commented out section of `spec_helper` rather than `.rspec` so users
+  have to consciously opt-in to the setting. (Andrew Hooker, #1572)
+* Update `spec_helper` generated by `rspec --init` so that it sets the new
+  rspec-expectations `include_chain_clauses_in_custom_matcher_descriptions`
+  config option (which will be on by default in RSpec 4) and also sets the
+  rspec-mocks `verify_partial_doubles` option (which will also default
+  to on in RSpec 4). (Myron Marston, #1647)
+* Provide an `inspect` output for example procsy objects (used in around
+  hooks) that doesn't make them look like procs. (Jon Rowe, #1620)
+* Remove a few unneeded `require` statements from
+  `rspec/core/rake_task.rb`, making it even more lighterweight.
+  (Myron Marston, #1640)
+* Allow rspec-core to be used when neither rspec-mocks or
+  rspec-expectations are installed, without requiring any
+  user configuration. (Sam Phippen, Myron Marston, #1615)
+* Don't filter out gems from backtraces by default. (The RSpec
+  gems will still be filtered). User feedback has indicated
+  that including gems in default backtraces will be useful.
+  (Myron Marston, #1641)
+* Add new `config.filter_gems_from_backtrace "rack", "rake"` API
+  to easily filter the named gems from backtraces. (Myron Marston, #1682)
+* Fix default backtrace filters so that the RSpec binary is
+  excluded when installing RSpec as a bundler `:git` dependency.
+  (Myron Marston, #1648)
+* Simplify command generated by the rake task so that it no longer
+  includes unnecessary `-S`. (Myron Marston, #1559)
+* Add `--exclude-pattern` CLI option, `config.exclude_pattern =` config
+  option and `task.exclude_pattern =` rake task config option. Matching
+  files will be excluded. (John Gesimondo, Myron Marston, #1651, #1671)
+* When an around hook fails to execute the example, mark it as
+  pending (rather than passing) so the user is made aware of the
+  fact that the example did not actually run. (Myron Marston, #1660)
+* Remove dependency on `FileUtils` from the standard library so that users do
+  not get false positives where their code relies on it but they are not
+  requiring it. (Sam Phippen, #1565)
+
+Bug Fixes:
+
+* Fix rake task `t.pattern =` option so that it does not run all specs
+  when it matches no files, by passing along a `--pattern` option to
+  the `rspec` command, rather than resolving the file list and passing
+  along the files individually. (Evgeny Zislis, #1653)
+* Fix rake task default pattern so that it follows symlinks properly.
+  (Myron Marston, #1672)
+* Fix default pattern used with `rspec` command so that it follows
+  symlinks properly. (Myron Marston, #1672)
+* Change how we assign constant names to example group classes so that
+  it avoids a problem with `describe "Core"`. (Daniela Wellisz, #1679)
+* Handle rendering exceptions that have a different encoding than that
+  of their original source file. (Jon Rowe, #1681)
+* Allow access to message_lines without colour for failed examples even
+  when they're part of a shared example group. (tomykaira, #1689)
+
+### 3.0.4 / 2014-08-14
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.3...v3.0.4)
+
+Bug Fixes:
+
+* Fix processing order of CLI options so that if `config.files_to_run`
+  is accessed from a file loaded by `--require`, `--pattern` is still
+  applied. (Myron Marston, #1652)
+* Fix `config.pattern=` so that it still takes affect even if
+  `config.files_to_run` has already been accessed. (Myron Marston, #1652)
+
+### 3.0.3 / 2014-07-21
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.2...v3.0.3)
+
+Bug Fixes:
+
+* Properly convert both parts of a description into strings before
+  concatenation.  (@nicklink483, #1636)
+* Exclude the working directory when figuring out folders to ignore.
+  (Jon Rowe, Myron Marston, #1616)
+* Allow `::RSpec::Core::Notifications::FailedExampleNotification#message_lines`
+  to be accessed without a colouriser. (@tomykaira, #1637)
+
+### 3.0.2 / 2014-06-19
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.1...v3.0.2)
+
+Bug Fixes:
+
+* Fix regression in CLI option handling that prevented `--tag slow`
+  passed at the command line from overriding `--tag ~slow` in `.rspec`.
+  (Colin Jones, #1602)
+* Fix metadata `:example_group` deprecation warning so that it gets
+  issued at the call site of the configuration that specified it as
+  a filter rather than later when an example group is defined.
+  (Myron Marston, #1562)
+* Make the line that is printed when a shared example group fails indicating
+  where the concrete example group is white, separating it from the stack trace
+  that is produced for the failure. (Sam Phippen, Jon Rowe, #1606)
+
+### 3.0.1 / 2014-06-12
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0...v3.0.1)
+
+Bug Fixes:
+
+* Fix a couple ruby warnings caused by rspec-core when loaded.
+  (Prem Sichanugrist, #1584)
+* Example groups named `Config` will no longer cause a Ruby warning to be
+  issued. (Jimmy Cuadra, #1580)
+
+### 3.0.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.rc1...v3.0.0)
+
+Bug Fixes:
+
+* Fix `BaseTextFormatter` so that it does not re-close a closed output
+  stream. (Myron Marston)
+* Fix regression in metadata that caused the metadata hash of a top-level
+  example group to have a `:parent_example_group` key even though it has
+  no parent example group. (Myron Marston)
+
+Enhancements:
+
+* Alter the default `spec_helper.rb` to no longer recommend
+  `config.full_backtrace = true` see #1536 for discussion. (Jon Rowe)
+
+### 3.0.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.beta2...v3.0.0.rc1)
+
+Breaking Changes for 3.0.0:
+
+* Change `described_class` so that in a nested group like `describe
+  MyClass`, it returns `MyClass` rather than the outer group's described
+  class. (Myron Marston)
+* Refactor filter manager so that it no longer subclasses Hash and has a
+  tighter, more domain-specific interface. (Sergey Pchelincev)
+* Remove legacy colours definitions from `BaseTextFormatter`. (Jon Rowe)
+* Remove console color definitions from `BaseTextFormatter`. (Jon Rowe)
+* Restructure example group metadata so that the computed keys are
+  exposed directly off of the metadata hash rather than being on
+  a nested `:example_group` subhash. In addition, the parent example
+  group metadata is now available as `[:parent_example_group]` rather
+  than `[:example_group][:example_group]`. Deprecated access via the
+  old key structure is still provided. (Myron Marston)
+* Remove `:describes` metadata key. It duplicates `:described_class`
+  for no good reason. Deprecated access via `:describes` is still
+  provided. (Myron Marston)
+* Rename `:example_group_block` metadata key to `:block`.
+  (Myron Marston)
+* Remove deprecated `RSpec::Core::Example#options`. (Myron Marston)
+* Move `BaseTextFormatter#colorize_summary` to `SummaryNotification#colorize_with`
+  (Jon Rowe).
+* `describe some_hash` treated `some_hash` as metadata in RSpec 2.x but
+  will treat it as the described object in RSpec 3.0. Metadata must
+  always come after the description args. (Myron Marston)
+* Remove deprecated `display_name` alias of `ExampleGroup.description`.
+  (Myron Marston)
+* Remove deprecated `describes` alias of `ExampleGroup.described_class`.
+  (Myron Marston)
+* Remove deprecated `RSpec::Core::ExampleGroup.alias_it_behaves_like_to`.
+  Use `RSpec::Core::Configuration#alias_it_behaves_like_to` instead.
+  (Myron Marston)
+* Remove deprecated `RSpec::Core::ExampleGroup.alias_example_to`.
+  Use `RSpec::Core::Configuration#alias_example_to` instead.
+  (Myron Marston)
+* Removed `focused` example alias and change example/group aliases
+  `fit`, `focus`, `fcontext` and `fdescribe` to no longer include
+  `:focused => true` metadata. They only contain `:focus => true`
+  metadata now. This means that you will need to filter them with
+  `filter_run :focus`, not `filter_run :focused`. (Myron Marston)
+* Remove `--line-number` filtering. It's semantically dubious since it's
+  a global filter (potentially applied to multiple files) but there's no
+  meaningful connection between the same line number in multiple files.
+  Instead use the `rspec path/to/spec.rb:23:46` form, which is terser
+  and makes more sense as it is scoped to a file. (Myron Marston)
+* Remove `--default_path` as an alias for `--default-path`. (Jon Rowe)
+* Remove deprecated `share_examples_for`. There's still
+  `shared_examples` and `shared_examples_for`. (Myron Marston)
+* Rename `RSpec::Core::Configuration#warnings` to
+  `RSpec::Core::Configuration#warnings?` since it's a boolean flag.
+  (Myron Marston)
+* RSpec's global state is no longer reset after a spec run. This gives
+  more flexibility to alternate runners to decide when and if they
+  want the state reset. Alternate runners are now responsible for
+  calling this (or doing a similar reset) if they are going to run
+  the spec suite multiple times in the same process. (Sam Phippen)
+* Merge `RSpec::Core::CommandLine` (never formally declared public)
+  into `RSpec::Core::Runner`. (Myron Marston)
+* Remove `color_enabled` as an alias of `color`. (Jon Rowe)
+* Remove `backtrace_cleaner` as an alias of `backtrace_formatter`. (Jon Rowe)
+* Remove `filename_pattern` as an alias of `pattern`. (Jon Rowe)
+* Extract support for legacy formatters to `rspec-legacy_formatters`. (Jon Rowe)
+* `RSpec::Configuration#formatters` now returns a dup to prevent mutation. (Jon Rowe)
+* Replace `stdlib` as an available expectation framework with `test_unit` and
+  `minitest`. (Aaron Kromer)
+* Remove backtrace formatting helpers from `BaseTextFormatter`. (Jon Rowe)
+* Extract profiler support to `ProfileFormatter` and `ProfileNotification`.
+  Formatters should implement `dump_profile` if they wish to respond to `--profile`.
+  (Jon Rowe)
+* Extract remaining formatter state to reporter and notifications. Introduce
+  `ExamplesNotification` to share information about examples that was previously
+  held in `BaseFormatter`. (Jon Rowe)
+
+Enhancements:
+
+* Add `config.default_formatter` attribute, which can be used to set a
+  formatter which will only be used if no other formatter is set
+  (e.g. via `--formatter`). (Myron Marston)
+* Support legacy colour definitions in `LegacyFormatterAdaptor`. (Jon Rowe)
+* Migrate `execution_result` (exposed by metadata) from a hash to a
+  first-class object with appropriate attributes. `status` is now
+  stored and returned as a symbol rather than a string. It retains
+  deprecated hash behavior for backwards compatibility. (Myron Marston)
+* Provide console code helper for formatters. (Jon Rowe)
+* Use raw ruby hashes for the metadata hashes rather than a subclass of
+  a hash. Computed metadata entries are now computed in advance rather
+  than being done lazily on first access. (Myron Marston)
+* Add `:block` metadata entry to the example metadata, bringing
+  parity with `:block` in the example group metadata. (Myron Marston)
+* Add `fspecify` and `fexample` as aliases of `specify` and `example`
+  with `:focus => true` metadata for parity with `fit`. (Myron Marston)
+* Add legacy support for `colorize_summary`. (Jon Rowe)
+* Restructure runner so it can be more easily customized in a subclass
+  for an alternate runner. (Ben Hoskings)
+* Document `RSpec::Core::ConfigurationOptions` as an officially
+  supported public API. (Myron Marston)
+* Add `--deprecation-out` CLI option which directs deprecation warnings
+  to the named file. (Myron Marston)
+* Minitest 5 compatability for `expect_with :stdlib` (now available as
+  `expect_with :minitest`). (Xavier Shay)
+* Reporter now notifies formatters of the load time of RSpec and your
+  specs via `StartNotification` and `SummaryNotification`. (Jon Rowe)
+* Add `disable_monkey_patching!` config option that disables all monkey
+  patching from whatever pieces of RSpec you use. (Alexey Fedorov)
+* Add `Pathname` support for setting all output streams. (Aaron Kromer)
+* Add `config.define_derived_metadata`, which can be used to apply
+  additional metadata to all groups or examples that match a given
+  filter. (Myron Marston)
+* Provide formatted and colorized backtraces via `FailedExampleNotification`
+  and send `PendingExampleFixedNotifications` when the error is due to a
+  passing spec you expect to fail. (Jon Rowe)
+* Add `dump_profile` to formatter API to allow formatters to implement
+  support for `--profile`. (Jon Rowe)
+* Allow colourising text via `ConsoleCodes` with RSpec 'states'
+  (e.g. `:success`, `:failure`) rather than direct colour codes. (Jon Rowe)
+* Expose `fully_formatted` methods off the formatter notification objects
+  that make it easy for a custom formatter to produce formatted output
+  like rspec-core's. (Myron Marston)
+
+Bug Fixes:
+
+* Fix `spec_helper.rb` file generated by `rspec --init` so that the
+  recommended settings correctly use the documentation formatter
+  when running one file. (Myron Marston)
+* Fix ordering problem where descriptions were generated after
+  tearing down mocks, which resulted in unexpected exceptions.
+  (Bradley Schaefer, Aaron Kromer, Andrey Savchenko)
+* Allow a symbol to be used as an implicit subject (e.g. `describe
+  :foo`). (Myron Marston)
+* Prevent creating an isolated context (i.e. using `RSpec.describe`) when
+  already inside a context. There is no reason to do this, and it could
+  potentially cause unexpected bugs. (Xavier Shay)
+* Fix shared example group scoping so that when two shared example
+  groups share the same name at different levels of nested contexts,
+  the one in the nearest context is used. (Myron Marston)
+* Fix `--warnings` option so that it enables warnings immediately so
+  that it applies to files loaded by `--require`. (Myron Marston)
+* Issue a warning when you set `config.deprecation_stream` too late for
+  it to take effect because the reporter has already been setup. (Myron Marston)
+* Add the full `RSpec::Core::Example` interface to the argument yielded
+  to `around` hooks. (Myron Marston)
+* Line number always takes precendence when running specs with filters.
+  (Xavier Shay)
+* Ensure :if and :unless metadata filters are treated as a special case
+  and are always in-effect. (Bradley Schaefer)
+* Ensure the currently running installation of RSpec is used when
+  the rake task shells out to `rspec`, even if a newer version is also
+  installed. (Postmodern)
+* Using a legacy formatter as default no longer causes an infinite loop.
+  (Xavier Shay)
+
+### 3.0.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.0.0.beta1...v3.0.0.beta2)
+
+Breaking Changes for 3.0.0:
+
+* Make `mock_with` option more strict. Strings are no longer supported
+  (e.g. `mock_with "mocha"`) -- use a symbol instead. Also, unrecognized
+  values will now result in an error rather than falling back to the
+  null mocking adapter. If you want to use the null mocking adapter,
+  use `mock_with :nothing` (as has been documented for a long time).
+  (Myron Marston)
+* Remove support for overriding RSpec's built-in `:if` and `:unless`
+  filters. (Ashish Dixit)
+* Custom formatters are now required to call
+  `RSpec::Core::Formatters.register(formatter_class, *notifications)`
+  where `notifications` is the list of events the formatter wishes to
+  be notified about. Notifications are handled by methods matching the
+  names on formatters. This allows us to add or remove notifications
+  without breaking existing formatters. (Jon Rowe)
+* Change arguments passed to formatters. Rather than passing multiple
+  arguments (which limits are ability to add additional arguments as
+  doing so would break existing formatters), we now pass a notification
+  value object that exposes the same data via attributes. This will
+  allow us to add new bits of data to a notification event without
+  breaking existing formatters. (Jon Rowe)
+* Remove support for deprecated `:alias` option for
+  `RSpec.configuration.add_setting`. (Myron Marston)
+* Remove support for deprecated `RSpec.configuration.requires = [...]`.
+  (Myron Marston)
+* Remove support for deprecated `--formatter` CLI option. (Myron Marston)
+* Remove support for deprecated `--configure` CLI option. (Myron Marston)
+* Remove support for deprecated `RSpec::Core::RakeTask#spec_opts=`.
+  (Myron Marston)
+* An example group level `pending` block or `:pending` metadata now executes
+  the example and cause a failure if it passes, otherwise it will be pending if
+  it fails. The old "never run" behaviour is still used for `xexample`, `xit`,
+  and `xspecify`, or via a new `skip` method or `:skip` metadata option.
+  (Xavier Shay)
+* After calling `pending` inside an example, the remainder of the example will
+  now be run. If it passes a failure is raised, otherwise the example is marked
+  pending. The old "never run" behaviour is provided a by a new `skip` method.
+  (Xavier Shay)
+* Pending blocks inside an example have been removed as a feature with no
+  direct replacement. Use `skip` or `pending` without a block. (Xavier Shay)
+* Pending statement is no longer allowed in `before(:all)` hooks. Use `skip`
+  instead.  (Xavier Shay)
+* Remove `show_failures_in_pending_blocks` configuration option. (Xavier Shay)
+* Remove support for specifying the documentation formatter using
+  's', 'n', 'spec' or 'nested'. (Jon Rowe)
+
+Enhancements:
+
+* Add example run time to JSON formatter output. (Karthik Kastury)
+* Add more suggested settings to the files generated by
+  `rspec --init`. (Myron Marston)
+* Add `config.alias_example_group_to`, which can be used to define a
+  new method that defines an example group with the provided metadata.
+  (Michi Huber)
+* Add `xdescribe` and `xcontext` as shortcuts to skip an example group.
+  (Myron Marston)
+* Add `fdescribe` and `fcontext` as shortcuts to focus an example group.
+  (Myron Marston)
+* Don't autorun specs via `#at_exit` by default. `require 'rspec/autorun'`
+  is only needed when running specs via `ruby`, as it always has been.
+  Running specs via `rake` or `rspec` are both unaffected. (Ben Hoskings)
+* Add `expose_dsl_globally` config option, defaulting to true. When disabled
+  it will remove the monkey patches rspec-core adds to `main` and `Module`
+  (e.g. `describe`, `shared_examples_for`, etc).  (Jon Rowe)
+* Expose RSpec DSL entry point methods (`describe`,
+  `shared_examples_for`, etc) on the `RSpec` constant. Intended for use
+  when `expose_dsl_globally` is set to `false`. (Jon Rowe)
+* For consistency, expose all example group aliases (including
+  `context`) on the `RSpec` constant. If `expose_dsl_globally` is set to
+  `true`, also expose them on `main` and `Module`. Historically, only `describe`
+  was exposed. (Jon Rowe, Michi Huber)
+* Add hook scope `:example` as an alias for `:each`, and `:context` as an alias
+  for `:all`. (John Feminella)
+
+Bug Fixes:
+
+* Fix failure (undefined method `path`) in end-of-run summary
+  when `raise_errors_for_deprecations!` is configured. (Myron Marston)
+* Issue error when attempting to use `-i` or `--I` on command line,
+  too close to `-I` to be considered short hand for `--init`. (Jon Rowe)
+* Prevent adding formatters to an output target if the same
+  formatter has already been added to that output. (Alex Peattie)
+* Allow a matcher-generated example description to be used when
+  the example is pending. (Myron Marston)
+* Ensure the configured `failure_exit_code` is used by the rake
+  task when there is a failure. (Jon Rowe)
+* Restore behaviour whereby system exclusion filters take priority over working
+  directory (was broken in beta1). (Jon Rowe)
+* Prevent RSpec mangling file names that have substrings containing `line_number`
+  or `default_path`. (Matijs van Zuijlen)
+* Fix failure line detection so that it handles relative file paths
+  (which can happen when running specs through `ruby` using `rspec/autorun`).
+  (Myron Marston, #1829)
+
+### 3.0.0.beta1 / 2013-11-07
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v3.0.0.beta1)
+
+Breaking Changes for 3.0.0:
+
+* Remove explicit support for 1.8.6. (Jon Rowe)
+* Remove `RSpec::Core::ExampleGroup#example` and
+  `RSpec::Core::ExampleGroup#running_example` methods. If you need
+  access to the example (e.g. to get its metadata), use a block arg
+  instead. (David Chelimsky)
+* Remove `TextMateFormatter`, it has been moved to `rspec-tmbundle`.
+  (Aaron Kromer)
+* Remove RCov integration. (Jon Rowe)
+* Remove deprecated support for RSpec 1 constructs (Myron Marston):
+  * The `Spec` and `Rspec` constants (rather than `RSpec`).
+  * `Spec::Runner.configure` rather than `RSpec.configure`.
+  * `Rake::SpecTask` rather than `RSpec::Core::RakeTask`.
+* Remove deprecated support for `share_as`. (Myron Marston)
+* Remove `--debug` option (and corresponding option on
+  `RSpec::Core::Configuration`). Instead, use `-r<debugger gem name>` to
+  load whichever debugger gem you wish to use (e.g. `ruby-debug`,
+  `debugger`, or `pry`). (Myron Marston)
+* Extract Autotest support to a seperate gem. (Jon Rowe)
+* Raise an error when a `let` or `subject` declaration is
+  accessed in a `before(:all)` or `after(:all)` hook. (Myron Marston)
+* Extract `its` support to a separate gem. (Peter Alfvin)
+* Disallow use of a shared example group from sibling contexts, making them
+  fully isolated. 2.14 and 2.99 allowed this but printed a deprecation warning.
+  (Jon Rowe)
+* Remove `RSpec::Core::Configuration#output` and
+  `RSpec::Core::Configuration#out` aliases of
+  `RSpec::Core::Configuration#output_stream`. (Myron Marston)
+* Remove legacy ordering APIs deprecated in 2.99.0.beta1. (Myron
+  Marston)
+
+Enhancements:
+
+* Replace unmaintained syntax gem with coderay gem. (Xavier Shay)
+* Times in profile output are now bold instead of `failure_color`.
+  (Matthew Boedicker)
+* Add `--no-fail-fast` command line option. (Gonzalo Rodríguez-Baltanás Díaz)
+* Runner now considers the local system ip address when running under Drb.
+  (Adrian CB)
+* JsonFormatter now includes `--profile` information. (Alex / @MasterLambaster)
+* Always treat symbols passed as metadata args as hash
+  keys with true values. RSpec 2 supported this with the
+  `treat_symbols_as_metadata_keys_with_true_values` but
+  now this behavior is always enabled. (Myron Marston)
+* Add `--dry-run` option, which prints the formatter output
+  of your suite without running any examples or hooks.
+  (Thomas Stratmann, Myron Marston)
+* Document the configuration options and default values in the `spec_helper.rb`
+  file that is generated by RSpec. (Parker Selbert)
+* Give generated example group classes a friendly name derived
+  from the docstring, rather than something like "Nested_2".
+  (Myron Marston)
+* Avoid affecting randomization of user code when shuffling
+  examples so that users can count on their own seeds
+  working. (Travis Herrick)
+* Ordering is no longer a single global property of the test suite.
+  Each group can pick an ordering using `:order` metadata. (Andy
+  Lindeman, Sam Phippen, Myron Marston)
+* Allow named custom ordering strategies to be registered, which can
+  then be used on individual example groups. (Andy Lindeman, Sam
+  Phippen, Myron Marston)
+
+Deprecations:
+
+* `treat_symbols_as_metadata_keys_with_true_values` is deprecated and no
+  longer has an affect now that the behavior it enabled is always
+  enabled. (Myron Marston)
+
+### 2.99.2 / 2014-08-19
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v2.99.2)
+
+Enhancements:
+
+* Improve deprecation warning for RSpec 3 change in `describe <a symbol>`
+  behavior. (Jon Rowe, #1667)
+
+### 2.99.1 / 2014-06-19
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0...v2.99.1)
+
+Bug Fixes:
+
+* Add missing deprecation warning for when `RSpec::Core::Runner` is used
+  multiple times in the same process. In 2.x RSpec's global state was
+  automatically cleared between runs but in 3.0 you need to call `RSpec.reset`
+  manually in these situations. (Sam Phippen, #1587)
+* Prevent deprecation being accidentally issues when doubles used with `be_`
+  matchers due to automatically generated descriptions. (Jon Rowe, #1573)
+* Load `rspec/core` when loading `rspec/core/rake_task` to ensure we can
+  issue deprecations correctly. (Jon Rowe, #1612)
+
+### 2.99.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.rc1...v2.99.0)
+
+Bug Fixes:
+
+* Fix `BaseTextFormatter` so that it does not re-close a closed output
+  stream. (Myron Marston)
+* Use `RSpec::Configuration#backtrace_exclusion_patterns` rather than the
+  deprecated `RSpec::Configuration#backtrace_clean_patterns` when mocking
+  with rr. (David Dollar)
+
+### 2.99.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.beta2...v2.99.0.rc1)
+
+Enhancements:
+
+* Add `--deprecation-out` CLI option which directs deprecation warnings
+  to the named file. (Myron Marston)
+* Backport support for `skip` in metadata to skip execution of an example.
+  (Xavier Shay, #1472)
+* Add `Pathname` support for setting all output streams. (Aaron Kromer)
+* Add `test_unit` and `minitest` expectation frameworks. (Aaron Kromer)
+
+Deprecations:
+
+* Deprecate `RSpec::Core::Pending::PendingDeclaredInExample`, use
+  `SkipDeclaredInExample` instead. (Xavier Shay)
+* Issue a deprecation when `described_class` is accessed from within
+  a nested `describe <SomeClass>` example group, since `described_class`
+  will return the innermost described class in RSpec 3 rather than the
+  outermost described class, as it behaved in RSpec 2. (Myron Marston)
+* Deprecate `RSpec::Core::FilterManager::DEFAULT_EXCLUSIONS`,
+  `RSpec::Core::FilterManager::STANDALONE_FILTERS` and use of
+  `#empty_without_conditional_filters?` on those filters. (Sergey Pchelincev)
+* Deprecate `RSpec::Core::Example#options` in favor of
+  `RSpec::Core::Example#metadata`. (Myron Marston)
+* Issue warning when passing a symbol or hash to `describe` or `context`
+  as the first argument. In RSpec 2.x this would be treated as metadata
+  but in RSpec 3 it'll be treated as the described object. To continue
+  having it treated as metadata, pass a description before the symbol or
+  hash. (Myron Marston)
+* Deprecate `RSpec::Core::BaseTextFormatter::VT100_COLORS` and
+  `RSpec::Core::BaseTextFormatter::VT100_COLOR_CODES` in favour
+  of `RSpec::Core::BaseTextFormatter::ConsoleCodes::VT100_CODES` and
+  `RSpec::Core::BaseTextFormatter::ConsoleCodes::VT100_CODE_VALUES`.
+  (Jon Rowe)
+* Deprecate `RSpec::Core::ExampleGroup.display_name` in favor of
+  `RSpec::Core::ExampleGroup.description`. (Myron Marston)
+* Deprecate `RSpec::Core::ExampleGroup.describes` in favor of
+  `RSpec::Core::ExampleGroup.described_class`. (Myron Marston)
+* Deprecate `RSpec::Core::ExampleGroup.alias_example_to` in favor of
+  `RSpec::Core::Configuration#alias_example_to`. (Myron Marston)
+* Deprecate `RSpec::Core::ExampleGroup.alias_it_behaves_like_to` in favor
+  of `RSpec::Core::Configuration#alias_it_behaves_like_to`. (Myron Marston)
+* Deprecate `RSpec::Core::ExampleGroup.focused` in favor of
+  `RSpec::Core::ExampleGroup.focus`. (Myron Marston)
+* Add deprecation warning for `config.filter_run :focused` since
+  example aliases `fit` and `focus` will no longer include
+  `:focused` metadata but will continue to include `:focus`. (Myron Marston)
+* Deprecate filtering by `:line_number` (e.g. `--line-number` from the
+  CLI). Use location filtering instead. (Myron Marston)
+* Deprecate `--default_path` as an alternative to `--default-path`. (Jon Rowe)
+* Deprecate `RSpec::Core::Configuration#warnings` in favor of
+  `RSpec::Core::Configuration#warnings?`. (Myron Marston)
+* Deprecate `share_examples_for` in favor of `shared_examples_for` or
+  just `shared_examples`. (Myron Marston)
+* Deprecate `RSpec::Core::CommandLine` in favor of
+  `RSpec::Core::Runner`. (Myron Marston)
+* Deprecate `#color_enabled`, `#color_enabled=` and `#color?` in favour of
+  `#color`, `#color=` and `#color_enabled? output`. (Jon Rowe)
+* Deprecate `#filename_pattern` in favour of `#pattern`. (Jon Rowe)
+* Deprecate `#backtrace_cleaner` in favour of `#backtrace_formatter`. (Jon Rowe)
+* Deprecate mutating `RSpec::Configuration#formatters`. (Jon Rowe)
+* Deprecate `stdlib` as an available expectation framework in favour of
+  `test_unit` and `minitest`. (Aaron Kromer)
+
+Bug Fixes:
+
+* Issue a warning when you set `config.deprecation_stream` too late for
+  it to take effect because the reporter has already been setup. (Myron Marston)
+* `skip` with a block should not execute the block. (Xavier Shay)
+
+### 2.99.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.0.beta1...v2.99.0.beta2)
+
+Enhancements:
+
+* Add `is_expected` for one-liners that read well with the
+  `expect`-based syntax. `is_expected` is simply defined as
+  `expect(subject)` and can be used in an expression like:
+  `it { is_expected.to read_well }`. (Myron Marston)
+* Backport `skip` from RSpec 3, which acts like `pending` did in RSpec 2
+  when not given a block, since the behavior of `pending` is changing in
+  RSpec 3. (Xavier Shay)
+
+Deprecations:
+
+* Deprecate inexact `mock_with` config options. RSpec 3 will only support
+  the exact symbols `:rspec`, `:mocha`, `:flexmock`, `:rr` or `:nothing`
+  (or any module that implements the adapter interface). RSpec 2 did
+  fuzzy matching but this will not be supported going forward.
+  (Myron Marston)
+* Deprecate `show_failures_in_pending_blocks` config option. To achieve
+  the same behavior as the option enabled, you can use a custom
+  formatter instead. (Xavier Shay)
+* Add a deprecation warning for the fact that the behavior of `pending`
+  is changing in RSpec 3 -- rather than skipping the example (as it did
+  in 2.x when no block was provided), it will run the example and mark
+  it as failed if no exception is raised. Use `skip` instead to preserve
+  the old behavior. (Xavier Shay)
+* Deprecate 's', 'n', 'spec' and 'nested' as aliases for documentation
+  formatter. (Jon Rowe)
+* Deprecate `RSpec::Core::Reporter#abort` in favor of
+  `RSpec::Core::Reporter#finish`. (Jon Rowe)
+
+Bug Fixes:
+
+* Fix failure (undefined method `path`) in end-of-run summary
+  when `raise_errors_for_deprecations!` is configured. (Myron Marston)
+* Fix issue were overridding spec ordering from the command line wasn't
+  fully recognised interally. (Jon Rowe)
+
+### 2.99.0.beta1 / 2013-11-07
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.7...v2.99.0.beta1)
+
+Enhancements
+
+* Block-based DSL methods that run in the context of an example
+  (`it`, `before(:each)`, `after(:each)`, `let` and `subject`)
+  now yield the example as a block argument. (David Chelimsky)
+* Warn when the name of more than one example group is submitted to
+  `include_examples` and it's aliases. (David Chelimsky)
+* Add `expose_current_running_example_as` config option for
+  use during the upgrade process when external gems use the
+  deprecated `RSpec::Core::ExampleGroup#example` and
+  `RSpec::Core::ExampleGroup#running_example` methods. (Myron Marston)
+* Limit spamminess of deprecation messages. (Bradley Schaefer, Loren Segal)
+* Add `config.raise_errors_for_deprecations!` option, which turns
+  deprecations warnings into errors to surface the full backtrace
+  of the call site. (Myron Marston)
+
+Deprecations
+
+* Deprecate `RSpec::Core::ExampleGroup#example` and
+  `RSpec::Core::ExampleGroup#running_example` methods. If you need
+  access to the example (e.g. to get its metadata), use a block argument
+  instead. (David Chelimsky)
+* Deprecate use of `autotest/rspec2` in favour of `rspec-autotest`. (Jon Rowe)
+* Deprecate RSpec's built-in debugger support. Use a CLI option like
+  `-rruby-debug` (for the ruby-debug gem) or `-rdebugger` (for the
+  debugger gem) instead. (Myron Marston)
+* Deprecate `RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values = false`.
+  RSpec 3 will not support having this option set to `false`. (Myron Marston)
+* Deprecate accessing a `let` or `subject` declaration in
+  a `after(:all)` hook. (Myron Marston, Jon Rowe)
+* Deprecate built-in `its` usage in favor of `rspec-its` gem due to planned
+  removal in RSpec 3. (Peter Alfvin)
+* Deprecate `RSpec::Core::PendingExampleFixedError` in favor of
+  `RSpec::Core::Pending::PendingExampleFixedError`. (Myron Marston)
+* Deprecate `RSpec::Core::Configuration#out` and
+  `RSpec::Core::Configuration#output` in favor of
+  `RSpec::Core::Configuration#output_stream`. (Myron Marston)
+* Deprecate legacy ordering APIs.
+  * You should use `register_ordering(:global)` instead of these:
+    * `RSpec::Core::Configuration#order_examples`
+    * `RSpec::Core::Configuration#order_groups`
+    * `RSpec::Core::Configuration#order_groups_and_examples`
+  * These are deprecated with no replacement because in RSpec 3
+    ordering is a property of individual example groups rather than
+    just a global property of the entire test suite:
+    * `RSpec::Core::Configuration#order`
+    * `RSpec::Core::Configuration#randomize?`
+  * `--order default` is deprecated in favor of `--order defined`
+  (Myron Marston)
+
+### 2.14.8 / 2014-02-27
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.7...v2.14.8)
+
+Bug fixes:
+
+* Fix regression with the `textmateformatter` that prevented backtrace links
+  from being clickable. (Stefan Daschek)
+
+### 2.14.7 / 2013-10-29
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.6...v2.14.7)
+
+Bug fixes:
+
+* Fix regression in 2.14.6 that broke the Fivemat formatter.
+  It depended upon either
+  `example.execution_result[:exception].pending_fixed?` (which
+  was removed in 2.14.6 to fix an issue with frozen error objects)
+  or `RSpec::Core::PendingExampleFixedError` (which was renamed
+  to `RSpec::Core::Pending::PendingExampleFixedError` in 2.8.
+  This fix makes a constant alias for the old error name.
+  (Myron Marston)
+
+### 2.14.6 / 2013-10-15
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.5...v2.14.6)
+
+Bug fixes:
+
+* Format stringified numbers correctly when mathn library is loaded.
+  (Jay Hayes)
+* Fix an issue that prevented the use of frozen error objects. (Lars
+  Gierth)
+
+### 2.14.5 / 2013-08-13
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.4...v2.14.5)
+
+Bug fixes:
+
+* Fix a `NoMethodError` that was being raised when there were no shared
+  examples or contexts declared and `RSpec.world.reset` is invoked.
+  (thepoho, Jon Rowe, Myron Marston)
+* Fix a deprecation warning that was being incorrectly displayed when
+  `shared_examples` are declared at top level in a `module` scope.
+  (Jon Rowe)
+* Fix after(:all) hooks so consecutive (same context) scopes will run even if
+  one raises an error. (Jon Rowe, Trejkaz)
+* JsonFormatter no longer dies if `dump_profile` isn't defined (Alex / @MasterLambaster, Jon Rowe)
+
+### 2.14.4 / 2013-07-21
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.3...v2.14.4)
+
+Bug fixes
+
+* Fix regression in 2.14: ensure configured requires (via `-r` option)
+  are loaded before spec files are loaded. This allows the spec files
+  to programatically change the file pattern (Jon Rowe).
+* Autoload `RSpec::Mocks` and `RSpec::Expectations` when referenced if
+  they are not already loaded (`RSpec::Matches` has been autoloaded
+  for a while). In the `rspec` gem, we changed it recently to stop
+  loading `rspec/mocks` and `rspec/expectations` by default, as some
+  users reported problems where they were intending to use mocha,
+  not rspec-mocks, but rspec-mocks was loaded and causing a conflict.
+  rspec-core loads mocks and expectations at the appropriate time, so
+  it seemed like a safe change -- but caused a problem for some authors
+  of libraries that integrate with RSpec. This fixes that problem.
+  (Myron Marston)
+* Gracefully handle a command like `rspec --profile path/to/spec.rb`:
+  the `path/to/spec.rb` arg was being wrongly treated as the `profile`
+  integer arg, which got cast `0` using `to_i`, causing no profiled
+  examples to be printed. (Jon Rowe)
+
+### 2.14.3 / 2013-07-13
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.2...v2.14.3)
+
+Bug fixes
+
+* Fix deprecation notices issued from `RSpec::Core::RakeTask` so
+  that they work properly when all of rspec-core is not loaded.
+  (This was a regression in 2.14) (Jon Rowe)
+
+### 2.14.2 / 2013-07-09
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.1...v2.14.2)
+
+Bug fixes
+
+* Fix regression caused by 2.14.1 release: formatters that
+  report that they `respond_to?` a notification, but had
+  no corresponding method would raise an error when registered.
+  The new fix is to just implement `start` on the deprecation
+  formatter to fix the original JRuby/ruby-debug issue.
+  (Jon Rowe)
+
+### 2.14.1 / 2013-07-08
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.0...v2.14.1)
+
+Bug fixes
+
+* Address deprecation formatter failure when using `ruby-debug` on
+  JRuby: fix `RSpec::Core::Reporter` to not send a notification
+  when the formatter's implementation of the notification method
+  comes from `Kernel` (Alex Portnov, Jon Rowe).
+
+### 2.14.0 / 2013-07-06
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.14.0.rc1...v2.14.0)
+
+Enhancements
+
+* Apply focus to examples defined with `fit` (equivalent of
+  `it "description", focus: true`) (Michael de Silva)
+
+Bug fix
+
+* Ensure methods defined by `let` take precedence over others
+  when there is a name collision (e.g. from an included module).
+  (Jon Rowe, Andy Lindeman and Myron Marston)
+
+### 2.14.0.rc1 / 2013-05-27
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.13.1...v2.14.0.rc1)
+
+Enhancements
+
+* Improved Windows detection inside Git Bash, for better `--color` handling.
+* Add profiling of the slowest example groups to `--profile` option.
+  The output is sorted by the slowest average example groups.
+* Don't show slow examples if there's a failure and both `--fail-fast`
+  and `--profile` options are used (Paweł Gościcki).
+* Rather than always adding `spec` to the load path, add the configured
+  `--default-path` to the load path (which defaults to `spec`). This
+  better supports folks who choose to put their specs in a different
+  directory (John Feminella).
+* Add some logic to test time duration precision. Make it a
+  function of time, dropping precision as the time increases. (Aaron Kromer)
+* Add new `backtrace_inclusion_patterns` config option. Backtrace lines
+  that match one of these patterns will _always_ be included in the
+  backtrace, even if they match an exclusion pattern, too (Sam Phippen).
+* Support ERB trim mode using the `-` when parsing `.rspec` as ERB
+  (Gabor Garami).
+* Give a better error message when let and subject are called without a block.
+  (Sam Phippen).
+* List the precedence of `.rspec-local` in the configuration documentation
+  (Sam Phippen)
+* Support `{a,b}` shell expansion syntax in `--pattern` option
+  (Konstantin Haase).
+* Add cucumber documentation for --require command line option
+  (Bradley Schaefer)
+* Expose configuration options via config:
+  * `config.libs` returns the libs configured to be added onto the load path
+  * `full_backtrace?` returns the state of the backtrace cleaner
+  * `debug?` returns true when the debugger is loaded
+  * `line_numbers` returns the line numbers we are filtering by (if any)
+  * `full_description` returns the RegExp used to filter descriptions
+  (Jon Rowe)
+* Add setters for RSpec.world and RSpec.configuration (Alex Soulim)
+* Configure ruby's warning behaviour with `--warnings` (Jon Rowe)
+* Fix an obscure issue on old versions of `1.8.7` where `Time.dup` wouldn't
+  allow access to `Time.now` (Jon Rowe)
+* Make `shared_examples_for` context aware, so that keys may be safely reused
+  in multiple contexts without colliding. (Jon Rowe)
+* Add a configurable `deprecation_stream` (Jon Rowe)
+* Publish deprecations through a formatter (David Chelimsky)
+
+Bug fixes
+
+* Make JSON formatter behave the same when it comes to `--profile` as
+  the text formatter (Paweł Gościcki).
+* Fix named subjects so that if an inner group defines a method that
+  overrides the named method, `subject` still retains the originally
+  declared value (Myron Marston).
+* Fix random ordering so that it does not cause `rand` in examples in
+  nested sibling contexts to return the same value (Max Shytikov).
+* Use the new `backtrace_inclusion_patterns` config option to ensure
+  that folks who develop code in a directory matching one of the default
+  exclusion patterns (e.g. `gems`) still get the normal backtrace
+  filtering (Sam Phippen).
+* Fix ordering of `before` hooks so that `before` hooks declared in
+  `RSpec.configure` run before `before` hooks declared in a shared
+  context (Michi Huber and Tejas Dinkar).
+* Fix `Example#full_description` so that it gets filled in by the last
+  matcher description (as `Example#description` already did) when no
+  doc string has been provided (David Chelimsky).
+* Fix the memoized methods (`let` and `subject`) leaking `define_method`
+  as a `public` method. (Thomas Holmes and Jon Rowe) (#873)
+* Fix warnings coming from the test suite. (Pete Higgins)
+
+Deprecations
+
+* Deprecate `Configuration#backtrace_clean_patterns` in favor of
+  `Configuration#backtrace_exclusion_patterns` for greater consistency
+  and symmetry with new `backtrace_inclusion_patterns` config option
+  (Sam Phippen).
+* Deprecate `Configuration#requires=` in favor of using ruby's
+  `require`. Requires specified by the command line can still be
+  accessed by the `Configuration#require` reader. (Bradley Schaefer)
+* Deprecate calling `SharedExampleGroups` defined across sibling contexts
+  (Jon Rowe)
+
+### 2.13.1 / 2013-03-12
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.13.0...v2.13.1)
+
+Bug fixes
+
+* Use hook classes as proxies rather than extending hook blocks to support
+  lambdas for before/after/around hooks. (David Chelimsky)
+* Fix regression in 2.13.0 that caused confusing behavior when overriding
+  a named subject with an unnamed subject in an inner group and then
+  referencing the outer group subject's name. The fix for this required
+  us to disallow using `super` in a named subject (which is confusing,
+  anyway -- named subjects create 2 methods, so which method on the
+  parent example group are you `super`ing to?) but `super` in an unnamed
+  subject continues to work (Myron Marston).
+* Do not allow a referenced `let` or `subject` in `before(:all)` to cause
+  other `let` declarations to leak across examples (Myron Marston).
+* Work around odd ruby 1.9 bug with `String#match` that was triggered
+  by passing it a regex from a `let` declaration. For more info, see
+  http://bugs.ruby-lang.org/issues/8059 (Aaron Kromer).
+* Add missing `require 'set'` to `base_text_formatter.rb` (Tom
+  Anderson).
+
+Deprecations
+
+* Deprecate accessing `let` or `subject` declarations in `before(:all)`.
+  These were not intended to be called in a `before(:all)` hook, as
+  they exist to define state that is reset between each example, while
+  `before(:all)` exists to define state that is shared across examples
+  in an example group (Myron Marston).
+
+### 2.13.0 / 2013-02-23
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.2...v2.13.0)
+
+Enhancements
+
+* Allow `--profile` option to take a count argument that
+  determines the number of slow examples to dump
+  (Greggory Rothmeier).
+* Add `subject!` that is the analog to `let!`. It defines an
+  explicit subject and sets a `before` hook that will invoke
+  the subject (Zubin Henner).
+* Fix `let` and `subject` declaration so that `super`
+  and `return` can be used in them, just like in a normal
+  method. (Myron Marston)
+* Allow output colors to be configured individually.
+  (Charlie Maffitt)
+* Always dump slow examples when `--profile` option is given,
+  even when an example failed (Myron Marston).
+
+Bug fixes
+
+* Don't blow up when dumping error output for instances
+  of anonymous error classes (Myron Marston).
+* Fix default backtrace filters so lines from projects
+  containing "gems" in the name are not filtered, but
+  lines from installed gems still are (Myron Marston).
+* Fix autotest command so that is uses double quotes
+  rather than single quotes for windows compatibility
+  (Jonas Tingeborn).
+* Fix `its` so that uses of `subject` in a `before` or `let`
+  declaration in the parent group continue to reference the
+  parent group's subject. (Olek Janiszewski)
+
+### 2.12.2 / 2012-12-13
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.1...v2.12.2)
+
+Bug fixes
+
+* Fix `RSpec::Core::RakeTask` so that it is compatible with rake 0.8.7
+  on ruby 1.8.7. We had accidentally broke it in the 2.12 release
+  (Myron Marston).
+* Fix `RSpec::Core::RakeTask` so it is tolerant of the `Rspec` constant
+  for backwards compatibility (Patrick Van Stee)
+
+### 2.12.1 / 2012-12-01
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.12.0...v2.12.1)
+
+Bug fixes
+
+* Specs are run even if another at\_exit hook calls `exit`. This allows
+  Test::Unit and RSpec to run together. (Suraj N. Kurapati)
+* Fix full doc string concatenation so that it handles the case of a
+  method string (e.g. "#foo") being nested under a context string
+  (e.g. "when it is tuesday"), so that we get "when it is tuesday #foo"
+  rather than "when it is tuesday#foo". (Myron Marston)
+* Restore public API I unintentionally broke in 2.12.0:
+  `RSpec::Core::Formatters::BaseFormatter#format_backtrce(backtrace, example)`
+  (Myron Marston).
+
+### 2.12.0 / 2012-11-12
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.11.1...v2.12.0)
+
+Enhancements
+
+* Add support for custom ordering strategies for groups and examples.
+  (Myron Marston)
+* JSON Formatter (Alex Chaffee)
+* Refactor rake task internals (Sam Phippen)
+* Refactor HtmlFormatter (Pete Hodgson)
+* Autotest supports a path to Ruby that contains spaces (dsisnero)
+* Provide a helpful warning when a shared example group is redefined.
+  (Mark Burns).
+* `--default_path` can be specified as `--default-line`. `--line_number` can be
+  specified as `--line-number`. Hyphens are more idiomatic command line argument
+  separators (Sam Phippen).
+* A more useful error message is shown when an invalid command line option is
+  used (Jordi Polo).
+* Add `format_docstrings { |str| }` config option. It can be used to
+  apply formatting rules to example group and example docstrings.
+  (Alex Tan)
+* Add support for an `.rspec-local` options file. This is intended to
+  allow individual developers to set options in a git-ignored file that
+  override the common project options in `.rspec`. (Sam Phippen)
+* Support for mocha 0.13.0. (Andy Lindeman)
+
+Bug fixes
+
+* Remove override of `ExampleGroup#ancestors`. This is a core ruby method that
+  RSpec shouldn't override. Instead, define `ExampleGroup#parent_groups`. (Myron
+  Marston)
+* Limit monkey patching of shared example/context declaration methods
+  (`shared_examples_for`, etc.) to just the objects that need it rather than
+  every object in the system (Myron Marston).
+* Fix Metadata#fetch to support computed values (Sam Goldman).
+* Named subject can now be referred to from within subject block in a nested
+  group (tomykaira).
+* Fix `fail_fast` so that it properly exits when an error occurs in a
+  `before(:all) hook` (Bradley Schaefer).
+* Make the order spec files are loaded consistent, regardless of the
+  order of the files returned by the OS or the order passed at
+  the command line (Jo Liss and Sam Phippen).
+* Ensure instance variables from `before(:all)` are always exposed
+  from `after(:all)`, even if an error occurs in `before(:all)`
+  (Sam Phippen).
+* `rspec --init` no longer generates an incorrect warning about `--configure`
+  being deprecated (Sam Phippen).
+* Fix pluralization of `1 seconds` (Odin Dutton)
+* Fix ANSICON url (Jarmo Pertman)
+* Use dup of Time so reporting isn't clobbered by examples that modify Time
+  without properly restoring it. (David Chelimsky)
+
+Deprecations
+
+* `share_as` is no longer needed. `shared_context` and/or
+  `RSpec::SharedContext` provide better mechanisms (Sam Phippen).
+* Deprecate `RSpec.configuration` with a block (use `RSpec.configure`).
+
+
+### 2.11.1 / 2012-07-18
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.11.0...v2.11.1)
+
+Bug fixes
+
+* Fix the way we autoload RSpec::Matchers so that custom matchers can be
+  defined before rspec-core has been configured to definitely use
+  rspec-expectations. (Myron Marston)
+* Fix typo in --help message printed for -e option. (Jo Liss)
+* Fix ruby warnings. (Myron Marston)
+* Ignore mock expectation failures when the example has already failed.
+  Mock expectation failures have always been ignored in this situation,
+  but due to my changes in 27059bf1 it was printing a confusing message.
+  (Myron Marston).
+
+### 2.11.0 / 2012-07-07
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.10.1...v2.11.0)
+
+Enhancements
+
+* Support multiple `--example` options. (Daniel Doubrovkine @dblock)
+* Named subject e.g. `subject(:article) { Article.new }`
+    * see [http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/](http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/)
+      for background.
+    * thanks to Bradley Schaefer for suggesting it and Avdi Grimm for almost
+      suggesting it.
+* `config.mock_with` and `config.expect_with` yield custom config object to a
+  block if given
+    * aids decoupling from rspec-core's configuation
+* `include_context` and `include_examples` support a block, which gets eval'd
+  in the current context (vs the nested context generated by `it_behaves_like`).
+* Add `config.order = 'random'` to the `spec_helper.rb` generated by `rspec
+  --init`.
+* Delay the loading of DRb (Myron Marston).
+* Limit monkey patching of `describe` onto just the objects that need it rather
+  than every object in the system (Myron Marston).
+
+Bug fixes
+
+* Support alternative path separators. For example, on Windows, you can now do
+  this: `rspec spec\subdir`. (Jarmo Pertman @jarmo)
+* When an example raises an error and an after or around hook does as
+  well, print out the hook error. Previously, the error was silenced and
+  the user got no feedback about what happened. (Myron Marston)
+* `--require` and `-I` are merged among different configuration sources (Andy
+  Lindeman)
+* Delegate to mocha methods instead of aliasing them in mocha adapter.
+
+### 2.10.1 / 2012-05-19
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.10.0...v2.10.1)
+
+Bug fixes
+
+* `RSpec.reset` properly reinits configuration and world
+* Call `to_s` before `split` on exception messages that might not always be
+  Strings (slyphon)
+
+### 2.10.0 / 2012-05-03
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.9.0...v2.10.0)
+
+Enhancements
+
+* Add `prepend_before` and `append_after` hooks (preethiramdev)
+    * intended for extension libs
+    * restores rspec-1 behavior
+* Reporting of profiled examples (moro)
+    * Report the total amount of time taken for the top slowest examples.
+    * Report what percentage the slowest examples took from the total runtime.
+
+Bug fixes
+
+* Properly parse `SPEC_OPTS` options.
+* `example.description` returns the location of the example if there is no
+  explicit description or matcher-generated description.
+* RDoc fixes (Grzegorz Świrski)
+* Do not modify example ancestry when dumping errors (Michael Grosser)
+
+### 2.9.0 / 2012-03-17
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0...v2.9.0)
+
+Enhancements
+
+* Support for "X minutes X seconds" spec run duration in formatter. (uzzz)
+* Strip whitespace from group and example names in doc formatter.
+* Removed spork-0.9 shim. If you're using spork-0.8.x, you'll need to upgrade
+  to 0.9.0.
+
+Bug fixes
+
+* Restore `--full_backtrace` option
+* Ensure that values passed to `config.filter_run` are respected when running
+  over DRb (using spork).
+* Ensure shared example groups are reset after a run (as example groups are).
+* Remove `rescue false` from calls to filters represented as Procs
+* Ensure `described_class` gets the closest constant (pyromaniac)
+* In "autorun", don't run the specs in the `at_exit` hook if there was an
+  exception (most likely due to a SyntaxError). (sunaku)
+* Don't extend groups with modules already used to extend ancestor groups.
+* `its` correctly memoizes nil or false values (Yamada Masaki)
+
+### 2.8.0 / 2012-01-04
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0.rc2...v2.8.0)
+
+Bug fixes
+
+* For metadata filtering, restore passing the entire array to the proc, rather
+  than each item in the array (weidenfreak)
+* Ensure each spec file is loaded only once
+    * Fixes a bug that caused all the examples in a file to be run when
+      referenced twice with line numbers in a command, e.g.
+        * `rspec path/to/file:37 path/to/file:42`
+
+### 2.8.0.rc2 / 2011-12-19
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.8.0.rc1...v2.8.0.rc2)
+
+Enhancments
+
+* new `--init` command (Peter Schröder)
+    * generates `spec/spec_helper.rb`
+    * deletes obsolete files (on confirmation)
+    * merged with and deprecates `--configure` command, which generated
+      `.rspec`
+* use `require_relative` when available (Ian Leitch)
+* `include_context` and `include_examples` accept params (Calvin Bascom)
+* print the time for every example in the html formatter (Richie Vos)
+* several tasty refactoring niblets (Sasha)
+* `it "does something", :x => [:foo,'bar',/baz/] (Ivan Neverov)
+    * supports matching n command line tag values with an example or group
+
+### 2.8.0.rc1 / 2011-11-06
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.7.1...v2.8.0.rc1)
+
+Enhancements
+
+* `--order` (Justin Ko)
+    * run examples in random order: `--order rand`
+    * specify the seed: `--order rand:123`
+* `--seed SEED`
+    * equivalent of `--order rand:SEED`
+* SharedContext supports `let` (David Chelimsky)
+* Filter improvements (David Chelimsky)
+    * override opposing tags from the command line
+    * override RSpec.configure tags from the command line
+    * `--line_number 37` overrides all other filters
+    * `path/to/file.rb:37` overrides all other filters
+    * refactor: consolidate filter management in a FilterManger object
+* Eliminate Ruby warnings (Matijs van Zuijlen)
+* Make reporter.report an API (David Chelimsky)
+    * supports extension tools like interative_rspec
+
+Changes
+
+* change `config.color_enabled` (getter/setter/predicate) to `color` to align
+  with `--[no]-color` CLI option.
+    * `color_enabled` is still supported for now, but will likley be deprecated
+      in a 2.x release so we can remove it in 3.0.
+
+Bug fixes
+
+* Make sure the `bar` in `--tag foo:bar` makes it to DRb (Aaron Gibralter)
+* Fix bug where full descriptions of groups nested 3 deep  were repeated.
+* Restore report of time to run to start after files are loaded.
+    * fixes bug where run times were cumalitive in spork
+    * fixes compatibility with time-series metrics
+* Don't error out when `config.mock_with` or `expect_with` is re-specifying the
+  current config (Myron Marston)
+
+* Deprecations
+    * :alias option on `configuration.add_setting`. Use `:alias_with` on the
+      original setting declaration instead.
+
+### 2.7.1 / 2011-10-20
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.7.0...v2.7.1)
+
+Bug fixes
+
+* tell autotest the correct place to find the rspec executable
+
+### 2.7.0 / 2011-10-16
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.4...v2.7.0)
+
+NOTE: RSpec's release policy dictates that there should not be any backward
+incompatible changes in minor releases, but we're making an exception to
+release a change to how RSpec interacts with other command line tools.
+
+As of 2.7.0, you must explicity `require "rspec/autorun"` unless you use the
+`rspec` command (which already does this for you).
+
+Enhancements
+
+* Add `example.exception` (David Chelimsky)
+* `--default_path` command line option (Justin Ko)
+* support multiple `--line_number` options (David J. Hamilton)
+    * also supports `path/to/file.rb:5:9` (runs examples on lines 5 and 9)
+* Allow classes/modules to be used as shared example group identifiers (Arthur
+  Gunn)
+* Friendly error message when shared context cannot be found (Sławosz
+  Sławiński)
+* Clear formatters when resetting config (John Bintz)
+* Add `xspecify` and xexample as temp-pending methods (David Chelimsky)
+* Add `--no-drb` option (Iain Hecker)
+* Provide more accurate run time by registering start time before code is
+  loaded (David Chelimsky)
+    * reverted in 2.8.0
+* Rake task default pattern finds specs in symlinked dirs (Kelly Felkins)
+* Rake task no longer does anything to invoke bundler since Bundler already
+  handles it for us. Thanks to Andre Arko for the tip.
+* Add `--failure-exit-code` option (Chris Griego)
+
+Bug fixes
+
+* Include `Rake::DSL` to remove deprecation warnings in Rake > 0.8.7 (Pivotal
+  Casebook)
+* Only eval `let` block once even if it returns `nil` (Adam Meehan)
+* Fix `--pattern` option (wasn't being recognized) (David Chelimsky)
+* Only implicitly `require "rspec/autorun"` with the `rspec` command (David
+  Chelimsky)
+* Ensure that rspec's `at_exit` defines the exit code (Daniel Doubrovkine)
+* Show the correct snippet in the HTML and TextMate formatters (Brian Faherty)
+
+### 2.6.4 / 2011-06-06
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.3...v2.6.4)
+
+NOTE: RSpec's release policy dictates that there should not be new
+functionality in patch releases, but this minor enhancement slipped in by
+accident.  As it doesn't add a new API, we decided to leave it in rather than
+roll back this release.
+
+Enhancements
+
+* Add summary of commands to run individual failed examples.
+
+Bug fixes
+
+* Support exclusion filters in DRb. (Yann Lugrin)
+* Fix --example escaping when run over DRb. (Elliot Winkler)
+* Use standard ANSI codes for color formatting so colors work in a wider set of
+  color schemes.
+
+### 2.6.3 / 2011-05-24
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.2...v2.6.3)
+
+Bug fixes
+
+* Explicitly convert exit code to integer, avoiding TypeError when return
+  value of run is IO object proxied by `DRb::DRbObject` (Julian Scheid)
+* Clarify behavior of `--example` command line option
+* Build using a rubygems-1.6.2 to avoid downstream yaml parsing error
+
+### 2.6.2 / 2011-05-21
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.1...v2.6.2)
+
+Bug fixes
+
+* Warn rather than raise when HOME env var is not defined
+* Properly merge command-line exclusions with default :if and :unless (joshcooper)
+
+### 2.6.1 / 2011-05-19
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.6.0...v2.6.1)
+
+Bug fixes
+
+* Don't extend nil when filters are nil
+* `require 'rspec/autorun'` when running rcov.
+
+### 2.6.0 / 2011-05-12
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0)
+
+Enhancements
+
+* `shared_context` (Damian Nurzynski)
+    * extend groups matching specific metadata with:
+        * method definitions
+        * subject declarations
+        * let/let! declarations
+        * etc (anything you can do in a group)
+* `its([:key])` works for any subject with #[]. (Peter Jaros)
+* `treat_symbols_as_metadata_keys_with_true_values` (Myron Marston)
+* Print a deprecation warning when you configure RSpec after defining an
+  example.  All configuration should happen before any examples are defined.
+  (Myron Marston)
+* Pass the exit status of a DRb run to the invoking process. This causes specs
+  run via DRb to not just return true or false. (Ilkka Laukkanen)
+* Refactoring of `ConfigurationOptions#parse_options` (Rodrigo Rosenfeld Rosas)
+* Report excluded filters in runner output (tip from andyl)
+* Clean up messages for filters/tags.
+* Restore --pattern/-P command line option from rspec-1
+* Support false as well as true in config.full_backtrace= (Andreas Tolf
+  Tolfsen)
+
+Bug fixes
+
+* Don't stumble over an exception without a message (Hans Hasselberg)
+* Remove non-ascii characters from comments that were choking rcov (Geoffrey
+  Byers)
+* Fixed backtrace so it doesn't include lines from before the autorun at_exit
+  hook (Myron Marston)
+* Include RSpec::Matchers when first example group is defined, rather than just
+  before running the examples.  This works around an obscure bug in ruby 1.9
+  that can cause infinite recursion. (Myron Marston)
+* Don't send `example_group_[started|finished]` to formatters for empty groups.
+* Get specs passing on jruby (Sidu Ponnappa)
+* Fix bug where mixing nested groups and outer-level examples gave
+  unpredictable :line_number behavior (Artur Małecki)
+* Regexp.escape the argument to --example (tip from Elliot Winkler)
+* Correctly pass/fail pending block with message expectations
+* CommandLine returns exit status (0/1) instead of true/false
+* Create path to formatter output file if it doesn't exist (marekj).
+
+
+### 2.5.1 / 2011-02-06
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.5.0...v2.5.1)
+
+NOTE: this release breaks compatibility with rspec/autotest/bundler
+integration, but does so in order to greatly simplify it.
+
+With this release, if you want the generated autotest command to include
+'bundle exec', require Autotest's bundler plugin in a .autotest file in the
+project's root directory or in your home directory:
+
+    require "autotest/bundler"
+
+Now you can just type 'autotest' on the commmand line and it will work as you expect.
+
+If you don't want 'bundle exec', there is nothing you have to do.
+
+### 2.5.0 / 2011-02-05
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.4.0...v2.5.0)
+
+Enhancements
+
+* Autotest::Rspec2 parses command line args passed to autotest after '--'
+* --skip-bundler option for autotest command
+* Autotest regexp fixes (Jon Rowe)
+* Add filters to html and textmate formatters (Daniel Quimper)
+* Explicit passing of block (need for JRuby 1.6) (John Firebaugh)
+
+Bug fixes
+
+* fix dom IDs in HTML formatter (Brian Faherty)
+* fix bug with --drb + formatters when not running in drb
+* include --tag options in drb args (monocle)
+* fix regression so now SPEC_OPTS take precedence over CLI options again (Roman
+  Chernyatchik)
+* only call its(:attribute) once (failing example from Brian Dunn)
+* fix bizarre bug where rspec would hang after String.alias :to_int :to_i
+  (Damian Nurzynski)
+
+Deprecations
+
+* implicit inclusion of 'bundle exec' when Gemfile present (use autotest's
+  bundler plugin instead)
+
+### 2.4.0 / 2011-01-02
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.3.1...v2.4.0)
+
+Enhancements
+
+* start the debugger on -d so the stack trace is visible when it stops
+  (Clifford Heath)
+* apply hook filtering to examples as well as groups (Myron Marston)
+* support multiple formatters, each with their own output
+* show exception classes in failure messages unless they come from RSpec
+  matchers or message expectations
+* before(:all) { pending } sets all examples to pending
+
+Bug fixes
+
+* fix bug due to change in behavior of reject in Ruby 1.9.3-dev (Shota
+  Fukumori)
+* fix bug when running in jruby: be explicit about passing block to super (John
+  Firebaugh)
+* rake task doesn't choke on paths with quotes (Janmejay Singh)
+* restore --options option from rspec-1
+* require 'ostruct' to fix bug with its([key]) (Kim Burgestrand)
+* --configure option generates .rspec file instead of autotest/discover.rb
+
+### 2.3.1 / 2010-12-16
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.3.0...v2.3.1)
+
+Bug fixes
+
+* send debugger warning message to $stdout if RSpec.configuration.error_stream
+  has not been defined yet.
+* HTML Formatter _finally_ properly displays nested groups (Jarmo Pertman)
+* eliminate some warnings when running RSpec's own suite (Jarmo Pertman)
+
+### 2.3.0 / 2010-12-12
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.2.1...v2.3.0)
+
+Enhancements
+
+* tell autotest to use "rspec2" if it sees a .rspec file in the project's root
+  directory
+    * replaces the need for ./autotest/discover.rb, which will not work with
+      all versions of ZenTest and/or autotest
+* config.expect_with
+    * :rspec          # => rspec/expectations
+    * :stdlib         # => test/unit/assertions
+    * :rspec, :stdlib # => both
+
+Bug fixes
+
+* fix dev Gemfile to work on non-mac-os machines (Lake Denman)
+* ensure explicit subject is only eval'd once (Laszlo Bacsi)
+
+### 2.2.1 / 2010-11-28
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.2.0...v2.2.1)
+
+Bug fixes
+* alias_method instead of override Kernel#method_missing (John Wilger)
+* changed --autotest to --tty in generated command (MIKAMI Yoshiyuki)
+* revert change to debugger (had introduced conflict with Rails)
+    * also restored --debugger/-debug option
+
+### 2.2.0 / 2010-11-28
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.1.0...v2.2.0)
+
+Deprecations/changes
+
+* --debug/-d on command line is deprecated and now has no effect
+* win32console is now ignored; Windows users must use ANSICON for color support
+  (Bosko Ivanisevic)
+
+Enhancements
+
+* When developing locally rspec-core now works with the rspec-dev setup or your
+  local gems
+* Raise exception with helpful message when rspec-1 is loaded alongside rspec-2
+  (Justin Ko)
+* debugger statements _just work_ as long as ruby-debug is installed
+  * otherwise you get warned, but not fired
+* Expose example.metadata in around hooks
+* Performance improvments (much faster now)
+
+Bug fixes
+
+* Make sure --fail-fast makes it across drb
+* Pass -Ilib:spec to rcov
+
+### 2.1.0 / 2010-11-07
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.1...v2.1.0)
+
+Enhancments
+
+* Add skip_bundler option to rake task to tell rake task to ignore the presence
+  of a Gemfile (jfelchner)
+* Add gemfile option to rake task to tell rake task what Gemfile to look for
+  (defaults to 'Gemfile')
+* Allow passing caller trace into Metadata to support extensions (Glenn
+  Vanderburg)
+* Add deprecation warning for Spec::Runner.configure to aid upgrade from
+  RSpec-1
+* Add deprecated Spec::Rake::SpecTask to aid upgrade from RSpec-1
+* Add 'autospec' command with helpful message to aid upgrade from RSpec-1
+* Add support for filtering with tags on CLI (Lailson Bandeira)
+* Add a helpful message about RUBYOPT when require fails in bin/rspec (slyphon)
+* Add "-Ilib" to the default rcov options (Tianyi Cui)
+* Make the expectation framework configurable (default rspec, of course)
+  (Justin Ko)
+* Add 'pending' to be conditional (Myron Marston)
+* Add explicit support for :if and :unless as metadata keys for conditional run
+  of examples (Myron Marston)
+* Add --fail-fast command line option (Jeff Kreeftmeijer)
+
+Bug fixes
+
+* Eliminate stack overflow with "subject { self }"
+* Require 'rspec/core' in the Raketask (ensures it required when running rcov)
+
+### 2.0.1 / 2010-10-18
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0...v2.0.1)
+
+Bug fixes
+
+* Restore color when using spork + autotest
+* Pending examples without docstrings render the correct message (Josep M.
+  Bach)
+* Fixed bug where a failure in a spec file ending in anything but _spec.rb
+  would fail in a confusing way.
+* Support backtrace lines from erb templates in html formatter (Alex Crichton)
+
+### 2.0.0 / 2010-10-10
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.rc...v2.0.0)
+
+RSpec-1 compatibility
+
+* Rake task uses ENV["SPEC"] as file list if present
+
+Bug fixes
+
+* Bug Fix: optparse --out foo.txt (Leonardo Bessa)
+* Suppress color codes for non-tty output (except autotest)
+
+### 2.0.0.rc / 2010-10-05
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.beta.22...v2.0.0.rc)
+
+Enhancements
+
+* implicitly require unknown formatters so you don't have to require the file
+  explicitly on the commmand line (Michael Grosser)
+* add --out/-o option to assign output target
+* added fail_fast configuration option to abort on first failure
+* support a Hash subject (its([:key]) { should == value }) (Josep M. Bach)
+
+Bug fixes
+
+* Explicitly require rspec version to fix broken rdoc task (Hans de Graaff)
+* Ignore backtrace lines that come from other languages, like Java or
+  Javascript (Charles Lowell)
+* Rake task now does what is expected when setting (or not setting)
+  fail_on_error and verbose
+* Fix bug in which before/after(:all) hooks were running on excluded nested
+  groups (Myron Marston)
+* Fix before(:all) error handling so that it fails examples in nested groups,
+  too (Myron Marston)
+
+### 2.0.0.beta.22 / 2010-09-12
+
+[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.0.0.beta.20...v2.0.0.beta.22)
+
+Enhancements
+
+* removed at_exit hook
+* CTRL-C stops the run (almost) immediately
+    * first it cleans things up by running the appropriate after(:all) and
+      after(:suite) hooks
+    * then it reports on any examples that have already run
+* cleaned up rake task
+    * generate correct task under variety of conditions
+    * options are more consistent
+    * deprecated redundant options
+* run 'bundle exec autotest' when Gemfile is present
+* support ERB in .rspec options files (Justin Ko)
+* depend on bundler for development tasks (Myron Marston)
+* add example_group_finished to formatters and reporter (Roman Chernyatchik)
+
+Bug fixes
+
+* support paths with spaces when using autotest (Andreas Neuhaus)
+* fix module_exec with ruby 1.8.6 (Myron Marston)
+* remove context method from top-level
+    * was conflicting with irb, for example
+* errors in before(:all) are now reported correctly (Chad Humphries)
+
+Removals
+
+* removed -o --options-file command line option
+    * use ./.rspec and ~/.rspec
diff --git a/rspec-core/DEV-README.md b/rspec-core/DEV-README.md
new file mode 100644
index 0000000..0a32831
--- /dev/null
+++ b/rspec-core/DEV-README.md
@@ -0,0 +1,28 @@
+## Set up the dev environment
+
+    git clone git://github.com/rspec/rspec-core.git
+    cd rspec-core
+    gem install bundler
+    bundle install
+
+Now you should be able to run any of:
+
+    rake
+    rake spec
+    rake cucumber
+
+Or, if you prefer to use the rspec and cucumber commands directly, you can either:
+
+    bundle exec rspec
+
+Or ...
+
+    bundle install --binstubs
+    bin/rspec
+
+## Customize the dev enviroment
+
+The Gemfile includes the gems you'll need to be able to run specs. If you want
+to customize your dev enviroment with additional tools like guard or
+ruby-debug, add any additional gem declarations to Gemfile-custom (see
+Gemfile-custom.sample for some examples).
diff --git a/rspec-core/Filtering.md b/rspec-core/Filtering.md
new file mode 100644
index 0000000..5c00bdd
--- /dev/null
+++ b/rspec-core/Filtering.md
@@ -0,0 +1,161 @@
+# Filtering
+
+RSpec supports filtering examples and example groups in multiple ways,
+allowing you to run a targeted subset of your suite that you are
+currently interested in.
+
+## Filtering by Tag
+
+Examples and groups can be filtered by matching tags declared on
+the command line or options files, or filters declared via
+`RSpec.configure`, with hash key/values submitted within example group
+and/or example declarations. For example, given this declaration:
+
+``` ruby
+RSpec.describe Thing, :awesome => true do
+  it "does something" do
+    # ...
+  end
+end
+```
+
+That group (or any other with `:awesome => true`) would be filtered in
+with any of the following commands:
+
+    rspec --tag awesome:true
+    rspec --tag awesome
+    rspec -t awesome:true
+    rspec -t awesome
+
+Prefixing the tag names with `~` negates the tags, thus excluding this
+group with any of:
+
+    rspec --tag ~awesome:true
+    rspec --tag ~awesome
+    rspec -t ~awesome:true
+    rspec -t ~awesome
+
+## Filtering by Example description
+
+RSpec provides the `--example` (short form: `-e`) option to allow you to
+select examples or groups by their description. All loaded examples
+whose full description (computed based on the description of the example
+plus that of all ancestor groups) contains the provided argument will be
+executed.
+
+    rspec --example "Homepage when logged in"
+    rspec -e "Homepage when logged in"
+
+You can specify this option multiple times to select multiple sets of examples:
+
+    rspec -e "Homepage when logged in" -e "User"
+
+Note that RSpec will load all spec files in these situations, which can
+incur considerable start-up costs (particularly for Rails apps). If you
+know that the examples you are targeting are in particular files, you can
+also pass the file or directory name so that RSpec loads only those spec
+files, speeding things up:
+
+    rspec spec/homepage_spec.rb -e "Homepage when logged in"
+    rspec -e "Homepage when logged in" spec/homepage_spec.rb
+
+Note also that description-less examples that have generated descriptions
+(typical when using the one-liner syntax) cannot be directly filtered with
+this option, because it is necessary to execute the example to generate the
+description, so RSpec is unable to use the not-yet-generated description to
+decide whether or not to execute an example. You can, of course, pass part
+of a group's description to select all examples defined in the group
+(including those that have no description).
+
+## Filtering by Example Location
+
+Examples and groups can be selected from the command line by passing the
+file and line number where they are defined, separated by a colon:
+
+    rspec spec/homepage_spec.rb:14 spec/widgets_spec.rb:40 spec/users_spec.rb
+
+This command would run the example or group defined on line 14 of
+`spec/homepage_spec.rb`, the example or group defined on line 40 of
+`spec/widgets_spec.rb`, and all examples and groups defined in
+`spec/users_spec.rb`.
+
+If there is no example or group defined at the specified line, RSpec
+will run the last example or group defined before the line.
+
+## Focusing
+
+RSpec supports configuration options that make it easy to select
+examples by temporarily tweaking them. In your `spec_helper.rb` (or
+a similar file), put this configuration:
+
+``` ruby
+RSpec.configure do |config|
+  config.filter_run :focus
+  config.run_all_when_everything_filtered = true
+end
+```
+
+This configuration is generated for you by `rspec --init` in the
+commented-out section of recommendations. With that in place, you
+can tag any example group or example with `:focus` metadata to
+select it:
+
+``` ruby
+it "does something" do
+# becomes...
+it "does something", :focus do
+```
+
+RSpec also ships with aliases of the common example group definition
+methods (`describe`, `context`) and example methods (`it`, `specify`,
+`example`) with an `f` prefix that automatically includes `:focus =>
+true` metadata, allowing you to easily change `it` to `fit` (think
+"focused it"), `describe` to `fdescribe`, etc in order to temporarily
+focus them.
+
+## Options files and command line overrides
+
+Command line option declarations can be stored in `.rspec`, `~/.rspec`, or a custom
+options file. This is useful for storing defaults. For example, let's
+say you've got some slow specs that you want to suppress most of the
+time. You can tag them like this:
+
+``` ruby
+RSpec.describe Something, :slow => true do
+```
+
+And then store this in `.rspec`:
+
+    --tag ~slow:true
+
+Now when you run `rspec`, that group will be excluded.
+
+## Overriding
+
+Of course, you probably want to run them sometimes, so you can override
+this tag on the command line like this:
+
+    rspec --tag slow:true
+
+## Precedence
+
+Location and description filters have priority over tag filters since
+they express a desire by the user to run specific examples. Thus, you
+could specify a location or description at the command line to run an
+example or example group that would normally be excluded due to a
+`:slow` tag if you were using the above configuration.
+
+## RSpec.configure
+
+You can also store default tags with `RSpec.configure`. We use `tag` on
+the command line (and in options files like `.rspec`), but for historical
+reasons we use the term `filter` in `RSpec.configure`:
+
+``` ruby
+RSpec.configure do |c|
+  c.filter_run_including :foo => :bar
+  c.filter_run_excluding :foo => :bar
+end
+```
+
+These declarations can also be overridden from the command line.
diff --git a/rspec-core/Gemfile b/rspec-core/Gemfile
new file mode 100644
index 0000000..7726d77
--- /dev/null
+++ b/rspec-core/Gemfile
@@ -0,0 +1,35 @@
+source "https://rubygems.org"
+
+gemspec
+
+branch = File.read(File.expand_path("../maintenance-branch", __FILE__)).chomp
+%w[rspec rspec-expectations rspec-mocks rspec-support].each do |lib|
+  library_path = File.expand_path("../../#{lib}", __FILE__)
+  if File.exist?(library_path) && !ENV['USE_GIT_REPOS']
+    gem lib, :path => library_path
+  else
+    gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => branch
+  end
+end
+
+gem 'yard', '~> 0.8.7', :require => false
+
+### deps for rdoc.info
+group :documentation do
+  gem 'redcarpet',     '2.1.1', :platform => :mri
+  gem 'github-markup', '0.7.2', :platform => :mri
+end
+
+platforms :ruby_18, :jruby do
+  gem 'json'
+end
+
+platforms :jruby do
+  gem "jruby-openssl"
+end
+
+gem 'simplecov', '~> 0.8'
+gem 'rubocop', "~> 0.23.0", :platform => [:ruby_19, :ruby_20, :ruby_21]
+gem 'test-unit', '~> 3.0' if RUBY_VERSION.to_f >= 2.2
+
+eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
diff --git a/rspec-core/Gemfile-custom.sample b/rspec-core/Gemfile-custom.sample
new file mode 100644
index 0000000..8532039
--- /dev/null
+++ b/rspec-core/Gemfile-custom.sample
@@ -0,0 +1,19 @@
+group :development do
+  gem 'interactive_rspec'
+  gem 'relish', '~> 0.6.0'
+  gem 'guard-rspec', '~> 1.2.1'
+  gem 'growl', '1.0.3'
+  gem 'spork', '0.9.0'
+
+  platform :mri do
+    gem 'rb-fsevent', '~> 0.9.0'
+    gem 'ruby-prof', '~> 0.13.0'
+
+    case RUBY_VERSION
+    when /^1.8/
+      gem 'ruby-debug'
+    when /^1.9/
+      gem 'debugger'
+    end
+  end
+end
diff --git a/rspec-core/Guardfile b/rspec-core/Guardfile
new file mode 100644
index 0000000..b947f5a
--- /dev/null
+++ b/rspec-core/Guardfile
@@ -0,0 +1,5 @@
+guard 'rspec', :version => 2 do
+  watch(/^spec\/(.*)_spec.rb/)
+  watch(/^lib\/(.*)\.rb/)         { |m| "spec/#{m[1]}_spec.rb" }
+  watch(/^spec\/spec_helper.rb/)  { "spec" }
+end
diff --git a/License.txt b/rspec-core/License.txt
similarity index 94%
copy from License.txt
copy to rspec-core/License.txt
index 02bc06c..4bd202e 100644
--- a/License.txt
+++ b/rspec-core/License.txt
@@ -1,5 +1,6 @@
 (The MIT License)
 
+Copyright (c) 2012 Chad Humphries, David Chelimsky, Myron Marston
 Copyright (c) 2009 Chad Humphries, David Chelimsky
 Copyright (c) 2006 David Chelimsky, The RSpec Development Team
 Copyright (c) 2005 Steven Baker
diff --git a/rspec-core/README.md b/rspec-core/README.md
new file mode 100644
index 0000000..d47f17b
--- /dev/null
+++ b/rspec-core/README.md
@@ -0,0 +1,252 @@
+# rspec-core [![Build Status](https://secure.travis-ci.org/rspec/rspec-core.svg?branch=master)](http://travis-ci.org/rspec/rspec-core) [![Code Climate](https://codeclimate.com/github/rspec/rspec-core.svg)](https://codeclimate.com/github/rspec/rspec-core)
+
+rspec-core provides the structure for writing executable examples of how your
+code should behave, and an `rspec` command with tools to constrain which
+examples get run and tailor the output.
+
+## install
+
+    gem install rspec      # for rspec-core, rspec-expectations, rspec-mocks
+    gem install rspec-core # for rspec-core only
+    rspec --help
+
+Want to run against the `master` branch? You'll need to include the dependent
+RSpec repos as well. Add the following to your `Gemfile`:
+
+```ruby
+%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
+  gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => 'master'
+end
+```
+
+## basic structure
+
+RSpec uses the words "describe" and "it" so we can express concepts like a conversation:
+
+    "Describe an order."
+    "It sums the prices of its line items."
+
+```ruby
+RSpec.describe Order do
+  it "sums the prices of its line items" do
+    order = Order.new
+    order.add_entry(LineItem.new(:item => Item.new(
+      :price => Money.new(1.11, :USD)
+    )))
+    order.add_entry(LineItem.new(:item => Item.new(
+      :price => Money.new(2.22, :USD),
+      :quantity => 2
+    )))
+    expect(order.total).to eq(Money.new(5.55, :USD))
+  end
+end
+```
+
+The `describe` method creates an [ExampleGroup](http://rubydoc.info/gems/rspec-core/RSpec/Core/ExampleGroup).  Within the
+block passed to `describe` you can declare examples using the `it` method.
+
+Under the hood, an example group is a class in which the block passed to
+`describe` is evaluated. The blocks passed to `it` are evaluated in the
+context of an _instance_ of that class.
+
+## nested groups
+
+You can also declare nested nested groups using the `describe` or `context`
+methods:
+
+```ruby
+RSpec.describe Order do
+  context "with no items" do
+    it "behaves one way" do
+      # ...
+    end
+  end
+
+  context "with one item" do
+    it "behaves another way" do
+      # ...
+    end
+  end
+end
+```
+
+## aliases
+
+You can declare example groups using either `describe` or `context`.
+For a top level example group, `describe` and `context` are available
+off of `RSpec`. For backwards compatibility, they are also available
+off of the `main` object and `Module` unless you disable monkey
+patching.
+
+You can declare examples within a group using any of `it`, `specify`, or
+`example`.
+
+## shared examples and contexts
+
+Declare a shared example group using `shared_examples`, and then include it
+in any group using `include_examples`.
+
+```ruby
+RSpec.shared_examples "collections" do |collection_class|
+  it "is empty when first created" do
+    expect(collection_class.new).to be_empty
+  end
+end
+
+RSpec.describe Array do
+  include_examples "collections", Array
+end
+
+RSpec.describe Hash do
+  include_examples "collections", Hash
+end
+```
+
+Nearly anything that can be declared within an example group can be declared
+within a shared example group. This includes `before`, `after`, and `around`
+hooks, `let` declarations, and nested groups/contexts.
+
+You can also use the names `shared_context` and `include_context`. These are
+pretty much the same as `shared_examples` and `include_examples`, providing
+more accurate naming when you share hooks, `let` declarations, helper methods,
+etc, but no examples.
+
+## metadata
+
+rspec-core stores a metadata hash with every example and group, which
+contains their descriptions, the locations at which they were
+declared, etc, etc. This hash powers many of rspec-core's features,
+including output formatters (which access descriptions and locations),
+and filtering before and after hooks.
+
+Although you probably won't ever need this unless you are writing an
+extension, you can access it from an example like this:
+
+```ruby
+it "does something" do
+  expect(example.metadata[:description]).to eq("does something")
+end
+```
+
+### `described_class`
+
+When a class is passed to `describe`, you can access it from an example
+using the `described_class` method, which is a wrapper for
+`example.metadata[:described_class]`.
+
+```ruby
+RSpec.describe Widget do
+  example do
+    expect(described_class).to equal(Widget)
+  end
+end
+```
+
+This is useful in extensions or shared example groups in which the specific
+class is unknown. Taking the collections shared example group from above, we can
+clean it up a bit using `described_class`:
+
+```ruby
+RSpec.shared_examples "collections" do
+  it "is empty when first created" do
+    expect(described_class.new).to be_empty
+  end
+end
+
+RSpec.describe Array do
+  include_examples "collections"
+end
+
+RSpec.describe Hash do
+  include_examples "collections"
+end
+```
+
+## the `rspec` command
+
+When you install the rspec-core gem, it installs the `rspec` executable,
+which you'll use to run rspec. The `rspec` command comes with many useful
+options.
+Run `rspec --help` to see the complete list.
+
+## store command line options `.rspec`
+
+You can store command line options in a `.rspec` file in the project's root
+directory, and the `rspec` command will read them as though you typed them on
+the command line.
+
+## autotest integration
+
+rspec-core no longer ships with an Autotest extension, if you require Autotest
+integration, please use the `rspec-autotest` gem and see [rspec/rspec-autotest](https://github.com/rspec/rspec-autotest)
+for details
+
+## get started
+
+Start with a simple example of behavior you expect from your system. Do
+this before you write any implementation code:
+
+```ruby
+# in spec/calculator_spec.rb
+RSpec.describe Calculator do
+  describe '#add' do
+    it 'returns the sum of its arguments' do
+      expect(Calculator.new.add(1, 2)).to eq(3)
+    end
+  end
+end
+```
+
+Run this with the rspec command, and watch it fail:
+
+```
+$ rspec spec/calculator_spec.rb
+./spec/calculator_spec.rb:1: uninitialized constant Calculator
+```
+
+Implement the simplest solution:
+
+```ruby
+# in lib/calculator.rb
+class Calculator
+  def add(a,b)
+    a + b
+  end
+end
+```
+
+Be sure to require the implementation file in the spec:
+
+```ruby
+# in spec/calculator_spec.rb
+# - RSpec adds ./lib to the $LOAD_PATH
+require "calculator"
+```
+
+Now run the spec again, and watch it pass:
+
+```
+$ rspec spec/calculator_spec.rb
+.
+
+Finished in 0.000315 seconds
+1 example, 0 failures
+```
+
+Use the `documentation` formatter to see the resulting spec:
+
+```
+$ rspec spec/calculator_spec.rb --format doc
+Calculator
+  #add
+    returns the sum of its arguments
+
+Finished in 0.000379 seconds
+1 example, 0 failures
+```
+
+## Also see
+
+* [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
+* [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations)
+* [http://github.com/rspec/rspec-mocks](http://github.com/rspec/rspec-mocks)
diff --git a/rspec-core/Rakefile b/rspec-core/Rakefile
new file mode 100644
index 0000000..550f874
--- /dev/null
+++ b/rspec-core/Rakefile
@@ -0,0 +1,85 @@
+require "bundler"
+Bundler.setup
+Bundler::GemHelper.install_tasks
+
+require "rake"
+require "yaml"
+
+require "rspec/core/rake_task"
+
+require "cucumber/rake/task"
+Cucumber::Rake::Task.new(:cucumber)
+
+desc "Run all examples"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.ruby_opts = %w[-w]
+end
+
+namespace :spec do
+  desc "Run ui examples"
+  RSpec::Core::RakeTask.new(:ui) do |t|
+    t.ruby_opts = %w[-w]
+    t.rspec_opts = %w[--tag ui]
+  end
+end
+
+desc 'Run RuboCop on the lib directory'
+task :rubocop do
+  sh 'bundle exec rubocop lib'
+end
+
+desc "delete generated files"
+task :clobber do
+  sh 'find . -name "*.rbc" | xargs rm'
+  sh 'rm -rf pkg'
+  sh 'rm -rf tmp'
+  sh 'rm -rf coverage'
+  sh 'rm -rf .yardoc'
+  sh 'rm -rf doc'
+end
+
+desc "generate rdoc"
+task :rdoc do
+  sh "yardoc"
+end
+
+with_changelog_in_features = lambda do |&block|
+  begin
+    sh "cp Changelog.md features/"
+    block.call
+  ensure
+    sh "rm features/Changelog.md"
+  end
+end
+
+desc "Push docs/cukes to relishapp using the relish-client-gem"
+task :relish, :version do |_t, args|
+  raise "rake relish[VERSION]" unless args[:version]
+
+  with_changelog_in_features.call do
+    if `relish versions rspec/rspec-core`.split.map(&:strip).include? args[:version]
+      puts "Version #{args[:version]} already exists"
+    else
+      sh "relish versions:add rspec/rspec-core:#{args[:version]}"
+    end
+    sh "relish push rspec/rspec-core:#{args[:version]}"
+  end
+end
+
+desc "Push to relish staging environment"
+task :relish_staging do
+  with_changelog_in_features.call do
+    sh "relish push rspec-staging/rspec-core"
+  end
+end
+
+task :default => [:spec, :cucumber, :rubocop]
+
+task :verify_private_key_present do
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  unless File.exist?(private_key)
+    raise "Your private key is not present. This gem should not be built without that."
+  end
+end
+
+task :build => :verify_private_key_present
diff --git a/rspec-core/appveyor.yml b/rspec-core/appveyor.yml
new file mode 100644
index 0000000..9e4f457
--- /dev/null
+++ b/rspec-core/appveyor.yml
@@ -0,0 +1,34 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+version: "{build}"
+
+# This will build all PRs targetting matching branches.
+# Without this, each PR builds twice -- once for the PR branch HEAD,
+# and once for the merge commit that github creates for each mergable PR.
+branches:
+  only:
+    - master
+    - /.*-maintenance$/
+
+# Disable normal Windows builds in favor of our test script.
+build: off
+
+install:
+  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
+  - ruby --version
+  - gem --version
+  # We lock to 1.7.7 to avoid warnings from 1.7.8
+  - gem install bundler -v=1.7.7
+  - bundler --version
+  - bundle install
+  - cinst ansicon
+
+test_script:
+  - bundle exec rspec
+
+environment:
+  matrix:
+    # ruby_version: '20' doesn't work for some reason
+    - ruby_version: '193'
+    - ruby_version: '21'
diff --git a/rspec-core/benchmarks/README.md b/rspec-core/benchmarks/README.md
new file mode 100644
index 0000000..7e49bbb
--- /dev/null
+++ b/rspec-core/benchmarks/README.md
@@ -0,0 +1,4 @@
+## Benchmarks
+
+This directory contains various benchmarks we used to inform implementation
+decisions.
diff --git a/rspec-core/benchmarks/allocations/1000_groups_1_example.rb b/rspec-core/benchmarks/allocations/1000_groups_1_example.rb
new file mode 100644
index 0000000..756a2e0
--- /dev/null
+++ b/rspec-core/benchmarks/allocations/1000_groups_1_example.rb
@@ -0,0 +1,124 @@
+require_relative "helper"
+
+benchmark_allocations do
+  1000.times do |i|
+    RSpec.describe "group #{i}" do
+      it "has one example" do
+      end
+    end
+  end
+end
+
+__END__
+
+Original allocations:
+
+               class_plus                 count
+----------------------------------------  -----
+String                                    28000
+Array                                     15000
+RubyVM::Env                                9000
+Proc                                       9000
+Hash                                       9000
+RSpec::Core::Hooks::HookCollection         6000
+Array<String>                              5000
+MatchData                                  3000
+Array<String,Fixnum>                       2000
+Array<Module>                              2000
+Module                                     2000
+RSpec::Core::Example::ExecutionResult      2000
+RSpec::Core::Metadata::ExampleGroupHash    1000
+Class                                      1000
+Array<Hash>                                1000
+RSpec::Core::Hooks::AroundHookCollection   1000
+RSpec::Core::Hooks::HookCollections        1000
+RSpec::Core::Metadata::ExampleHash         1000
+RSpec::Core::Example                       1000
+Array<RSpec::Core::Example>                1000
+
+
+After removing `:suite` support from `Hooks` module,
+it cut Array and RSpec::Core::Hooks::HookCollection
+allocations by 2000 each:
+
+               class_plus                 count
+----------------------------------------  -----
+String                                    28000
+Array                                     13000
+Proc                                       9000
+RubyVM::Env                                9000
+Hash                                       9000
+Array<String>                              5000
+RSpec::Core::Hooks::HookCollection         4000
+MatchData                                  3000
+Array<Module>                              2000
+RSpec::Core::Example::ExecutionResult      2000
+Module                                     2000
+Array<String,Fixnum>                       2000
+RSpec::Core::Hooks::HookCollections        1000
+RSpec::Core::Example                       1000
+Array<RSpec::Core::Example>                1000
+RSpec::Core::Metadata::ExampleHash         1000
+RSpec::Core::Hooks::AroundHookCollection   1000
+RSpec::Core::Metadata::ExampleGroupHash    1000
+Class                                      1000
+Array<Hash>                                1000
+
+....
+
+Later, our allocations were:
+
+              class_plus                 count
+---------------------------------------  -----
+String                                   26000
+Hash                                     19000
+Array                                    18000
+Set                                      10000
+Proc                                      9000
+RubyVM::Env                               9000
+RSpec::Core::Hooks::HookCollection        5000
+RSpec::Core::FilterableItemRepository     5000
+Array<String>                             5000
+MatchData                                 3000
+RSpec::Core::Example::ExecutionResult     2000
+Array<String,Fixnum>                      2000
+Module                                    2000
+Array<Module>                             2000
+RSpec::Core::Metadata::ExampleGroupHash   1000
+Class                                     1000
+RSpec::Core::Metadata::ExampleHash        1000
+RSpec::Core::Example                      1000
+Array<RSpec::Core::Example>               1000
+Array<Hash>                               1000
+RSpec::Core::Hooks::HookCollections       1000
+
+
+After changing the hooks implementation to lazily
+instantiate `HookCollection` instances, it dropped
+our allocations by:
+  - 8K hashes
+  - 10K arrays
+  - 10K sets
+  - 5K FilterableItemRepository
+  - 5K HookCollecion
+
+              class_plus                 count
+---------------------------------------  -----
+String                                   26000
+Hash                                     11000
+Array                                     8000
+Proc                                      5000
+RubyVM::Env                               5000
+Array<String>                             5000
+MatchData                                 3000
+Array<Module>                             2000
+Array<String,Fixnum>                      2000
+RSpec::Core::Example::ExecutionResult     2000
+Module                                    2000
+Array<Hash>                               1000
+RSpec::Core::Metadata::ExampleGroupHash   1000
+Class                                     1000
+RSpec::Core::Metadata::ExampleHash        1000
+RSpec::Core::Example                      1000
+Array<RSpec::Core::Example>               1000
+RSpec::Core::Hooks::HookCollections       1000
diff --git a/rspec-core/benchmarks/allocations/1_group_1000_examples.rb b/rspec-core/benchmarks/allocations/1_group_1000_examples.rb
new file mode 100644
index 0000000..c058abd
--- /dev/null
+++ b/rspec-core/benchmarks/allocations/1_group_1000_examples.rb
@@ -0,0 +1,63 @@
+require_relative "helper"
+
+benchmark_allocations do
+  RSpec.describe "one example group" do
+    1000.times do |i|
+      example "example #{i}" do
+      end
+    end
+  end
+end
+
+__END__
+
+Original stats:
+
+               class_plus                 count
+----------------------------------------  -----
+String                                    22046
+Hash                                       3006
+Array<String>                              3002
+Proc                                       2007
+RubyVM::Env                                2007
+Array                                      1013
+Regexp                                     1001
+RSpec::Core::Example::ExecutionResult      1001
+Array<String,Fixnum>                       1001
+RSpec::Core::Example                       1000
+RSpec::Core::Metadata::ExampleHash         1000
+RSpec::Core::Hooks::HookCollection            6
+MatchData                                     4
+Array<Module>                                 2
+Module                                        2
+RSpec::Core::Metadata::ExampleGroupHash       1
+RSpec::Core::Hooks::AroundHookCollection      1
+Class                                         1
+Array<Hash>                                   1
+RSpec::Core::Hooks::HookCollections           1
+Array<RSpec::Core::Example>                   1
+
+After my fixes:
+
+               class_plus                 count
+----------------------------------------  -----
+String                                     6030
+Hash                                       3006
+Array<String>                              3002
+RubyVM::Env                                2007
+Proc                                       2007
+Array                                      1013
+RSpec::Core::Example::ExecutionResult      1001
+Array<String,Fixnum>                       1001
+RSpec::Core::Metadata::ExampleHash         1000
+RSpec::Core::Example                       1000
+RSpec::Core::Hooks::HookCollection            6
+MatchData                                     4
+Module                                        2
+Array<Module>                                 2
+RSpec::Core::Hooks::HookCollections           1
+Array<RSpec::Core::Example>                   1
+RSpec::Core::Hooks::AroundHookCollection      1
+RSpec::Core::Metadata::ExampleGroupHash       1
+Class                                         1
+Array<Hash>                                   1
diff --git a/rspec-core/benchmarks/allocations/helper.rb b/rspec-core/benchmarks/allocations/helper.rb
new file mode 100644
index 0000000..644f233
--- /dev/null
+++ b/rspec-core/benchmarks/allocations/helper.rb
@@ -0,0 +1,30 @@
+$LOAD_PATH.unshift File.expand_path("../../../lib", __FILE__)
+require 'rspec/core'
+require 'allocation_stats'
+
+def benchmark_allocations(burn: 1, min_allocations: 0)
+  stats = AllocationStats.new(burn: burn).trace do
+    yield
+  end
+
+  columns = if ENV['DETAIL']
+              [:sourcefile, :sourceline, :class_plus]
+            else
+              [:class_plus]
+            end
+
+  results = stats.allocations(alias_paths: true).group_by(*columns).from_pwd.sort_by_size.to_text
+  count_regex = /\s+(\d+)\z/
+
+  total_objects = results.split("\n").map { |line| line[count_regex, 1] }.compact.map { |c| Integer(c) }.inject(0, :+)
+
+  filtered = results.split("\n").select do |line|
+    count = line[count_regex, 1]
+    count.nil? || Integer(count) >= min_allocations
+  end
+
+  puts filtered.join("\n")
+  line_length = filtered.last.length
+  puts "-" * line_length
+  puts "Total:#{total_objects.to_s.rjust(line_length - "Total:".length)}"
+end
diff --git a/rspec-core/benchmarks/allocations/running_1000_groups_1_example.rb b/rspec-core/benchmarks/allocations/running_1000_groups_1_example.rb
new file mode 100644
index 0000000..b340f6d
--- /dev/null
+++ b/rspec-core/benchmarks/allocations/running_1000_groups_1_example.rb
@@ -0,0 +1,100 @@
+require_relative "helper"
+
+1000.times do |i|
+  RSpec.describe "group #{i}" do
+    it "has one example" do
+    end
+  end
+end
+
+benchmark_allocations(burn: 0, min_allocations: 50) do
+  RSpec::Core::Runner.run([])
+end
+
+__END__
+
+Before optimization:
+
+                                          class_plus                                             count
+-----------------------------------------------------------------------------------------------  -----
+Array<Symbol>                                                                                    26021
+String                                                                                           21331
+Array                                                                                            19402
+Array<Symbol,Proc>                                                                                6001
+Array<RSpec::Core::Example>                                                                       6001
+RSpec::Core::Hooks::HookCollection                                                                4004
+Array<Class>                                                                                      4004
+Hash                                                                                              3098
+Proc                                                                                              3096
+RubyVM::Env                                                                                       3056
+Time                                                                                              2002
+Random                                                                                            2001
+RSpec::Core::Hooks::AroundHookCollection                                                          2000
+RSpec::Core::Notifications::GroupNotification                                                     2000
+RSpec::Core::Notifications::ExampleNotification                                                   2000
+RSpec::Core::Hooks::GroupHookCollection                                                           2000
+Array<Symbol,TrueClass>                                                                           1003
+Array<Class,Module>                                                                               1002
+Array<TrueClass>                                                                                  1002
+RSpec::Core::Example::Procsy                                                                      1000
+RubyVM::InstructionSequence                                                                        506
+Array<Fixnum,FalseClass>                                                                           391
+Array<Array>                                                                                       205
+Array<String>                                                                                       52
+
+
+After optimization, we allocate 2000 less arrays and 2000 less RSpec::Core::Hooks::HookCollection
+instances. That's 2 less of each per example group.
+
+                                          class_plus                                             count
+-----------------------------------------------------------------------------------------------  -----
+Array<Symbol>                                                                                    26021
+String                                                                                           21331
+Array                                                                                            17400
+Array<Symbol,Proc>                                                                                6001
+Array<RSpec::Core::Example>                                                                       6001
+Array<Class>                                                                                      4004
+Hash                                                                                              3098
+Proc                                                                                              3096
+RubyVM::Env                                                                                       3056
+RSpec::Core::Hooks::HookCollection                                                                2002
+Time                                                                                              2002
+Random                                                                                            2001
+RSpec::Core::Notifications::ExampleNotification                                                   2000
+RSpec::Core::Notifications::GroupNotification                                                     2000
+RSpec::Core::Hooks::GroupHookCollection                                                           2000
+Array<Symbol,TrueClass>                                                                           1003
+Array<Class,Module>                                                                               1002
+Array<TrueClass>                                                                                  1002
+RSpec::Core::Example::Procsy                                                                      1000
+RSpec::Core::Hooks::AroundHookCollection                                                          1000
+RubyVM::InstructionSequence                                                                        506
+Array<Fixnum,FalseClass>                                                                           391
+Array<Array>                                                                                       205
+Array<String>                                                                                       52
+
+After yet further optimization (where HookCollection instances are only created when hooks are added),
+we've reduced allocations significantly further:
+
+                                          class_plus                                             count
+-----------------------------------------------------------------------------------------------  -----
+String                                                                                           21332
+Array                                                                                            13412
+Array<Symbol>                                                                                     6021
+Array<Symbol,Proc>                                                                                6001
+Array<RSpec::Core::Example>                                                                       6001
+Hash                                                                                              3105
+Array<Class>                                                                                      3004
+Proc                                                                                              2101
+RubyVM::Env                                                                                       2061
+Time                                                                                              2002
+Random                                                                                            2001
+RSpec::Core::Notifications::GroupNotification                                                     2000
+RSpec::Core::Notifications::ExampleNotification                                                   2000
+Array<Symbol,TrueClass>                                                                           1003
+Array<Class,Module>                                                                               1002
+Array<TrueClass>                                                                                  1002
+RubyVM::InstructionSequence                                                                        506
+Array<Fixnum,FalseClass>                                                                           391
+Array<Array>                                                                                       208
+Array<String>                                                                                       52
diff --git a/rspec-core/benchmarks/allocations/running_1_group_1000_examples.rb b/rspec-core/benchmarks/allocations/running_1_group_1000_examples.rb
new file mode 100644
index 0000000..506394a
--- /dev/null
+++ b/rspec-core/benchmarks/allocations/running_1_group_1000_examples.rb
@@ -0,0 +1,60 @@
+require_relative "helper"
+
+RSpec.describe "one example group" do
+  1000.times do |i|
+    example "example #{i}" do
+    end
+  end
+end
+
+benchmark_allocations(burn: 0) do
+  RSpec::Core::Runner.run([])
+end
+
+__END__
+
+Original allocations:
+
+                                          class_plus                                             count
+-----------------------------------------------------------------------------------------------  -----
+String                                                                                           35018
+Array<Symbol>                                                                                    14030
+Array                                                                                            12075
+RSpec::Core::Hooks::HookCollection                                                                4000
+Time                                                                                              2002
+Array<Symbol,Proc>                                                                                2000
+RSpec::Core::Hooks::AroundHookCollection                                                          2000
+RSpec::Core::Notifications::ExampleNotification                                                   2000
+Proc                                                                                              1065
+RubyVM::Env                                                                                       1018
+Array<Class>                                                                                      1006
+Array<RSpec::Core::Example>                                                                       1005
+RSpec::ExampleGroups::OneExampleGroup                                                             1002
+Array<String>                                                                                       67
+RubyVM::InstructionSequence                                                                         41
+Hash                                                                                                35
+Set                                                                                                 30
+File                                                                                                 6
+
+After my change:
+
+                                          class_plus                                             count
+-----------------------------------------------------------------------------------------------  -----
+Array<Symbol>                                                                                    14030
+String                                                                                           12967
+Array                                                                                            12075
+RSpec::Core::Hooks::HookCollection                                                                4000
+Time                                                                                              2002
+RSpec::Core::Notifications::ExampleNotification                                                   2000
+Array<Symbol,Proc>                                                                                2000
+RSpec::Core::Hooks::AroundHookCollection                                                          2000
+Proc                                                                                              1065
+RubyVM::Env                                                                                       1018
+Array<Class>                                                                                      1006
+Array<RSpec::Core::Example>                                                                       1005
+RSpec::ExampleGroups::OneExampleGroup                                                             1002
+Array<String>                                                                                       67
+RubyVM::InstructionSequence                                                                         41
+Hash                                                                                                35
+Set                                                                                                 30
+File                                                                                                 6
diff --git a/rspec-core/benchmarks/boot_time_with_many_load_path_dirs.sh b/rspec-core/benchmarks/boot_time_with_many_load_path_dirs.sh
new file mode 100755
index 0000000..09f5a88
--- /dev/null
+++ b/rspec-core/benchmarks/boot_time_with_many_load_path_dirs.sh
@@ -0,0 +1,123 @@
+ruby -v
+
+function run_benchmark_with_load_path_size {
+  pushd tmp
+  mkdir -p boot_time_benchmark
+
+  local load_path_size=$1
+  for (( i=0; i < $load_path_size; i++ )); do
+    mkdir -p "boot_time_benchmark/dir_$i"
+  done
+
+  local load_path=`ruby -e 'puts Array.new(Integer(ARGV.first)) { |i| "boot_time_benchmark/dir_#{i}" }.join(":")' $load_path_size`
+
+  echo "3 runs with $load_path_size dirs on load path, booting 50 times, using $2"
+  for i in {1..3}; do
+    time (for i in {1..50}; do ruby -I$load_path:../lib:../../rspec-support/lib -e 'require "rspec/core"'; done)
+  done
+  popd
+}
+
+run_benchmark_with_load_path_size 10   "require"
+run_benchmark_with_load_path_size 100  "require"
+run_benchmark_with_load_path_size 1000 "require"
+
+export REQUIRE_RELATIVE=1
+
+run_benchmark_with_load_path_size 10   "require_relative"
+run_benchmark_with_load_path_size 100  "require_relative"
+run_benchmark_with_load_path_size 1000 "require_relative"
+
+: <<'result_comment'
+ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
+~/code/rspec-core/tmp ~/code/rspec-core
+3 runs with 10 dirs on load path, booting 50 times, using require
+
+real  0m3.815s
+user  0m3.205s
+sys 0m0.519s
+
+real  0m3.850s
+user  0m3.234s
+sys 0m0.527s
+
+real  0m3.840s
+user  0m3.225s
+sys 0m0.525s
+~/code/rspec-core
+~/code/rspec-core/tmp ~/code/rspec-core
+3 runs with 100 dirs on load path, booting 50 times, using require
+
+real  0m5.086s
+user  0m3.887s
+sys 0m1.107s
+
+real  0m5.063s
+user  0m3.870s
+sys 0m1.098s
+
+real  0m5.061s
+user  0m3.871s
+sys 0m1.097s
+~/code/rspec-core
+~/code/rspec-core/tmp ~/code/rspec-core
+3 runs with 1000 dirs on load path, booting 50 times, using require
+
+real  0m18.850s
+user  0m11.057s
+sys 0m7.679s
+
+real  0m18.783s
+user  0m11.012s
+sys 0m7.657s
+
+real  0m18.747s
+user  0m10.992s
+sys 0m7.639s
+~/code/rspec-core
+~/code/rspec-core/tmp ~/code/rspec-core
+3 runs with 10 dirs on load path, booting 50 times, using require_relative
+
+real  0m3.794s
+user  0m3.200s
+sys 0m0.506s
+
+real  0m3.769s
+user  0m3.180s
+sys 0m0.502s
+
+real  0m3.787s
+user  0m3.192s
+sys 0m0.502s
+~/code/rspec-core
+~/code/rspec-core/tmp ~/code/rspec-core
+3 runs with 100 dirs on load path, booting 50 times, using require_relative
+
+real  0m4.626s
+user  0m3.620s
+sys 0m0.910s
+
+real  0m4.652s
+user  0m3.642s
+sys 0m0.915s
+
+real  0m4.678s
+user  0m3.662s
+sys 0m0.924s
+~/code/rspec-core
+~/code/rspec-core/tmp ~/code/rspec-core
+3 runs with 1000 dirs on load path, booting 50 times, using require_relative
+
+real  0m14.400s
+user  0m8.615s
+sys 0m5.675s
+
+real  0m14.495s
+user  0m8.672s
+sys 0m5.711s
+
+real  0m14.541s
+user  0m8.705s
+sys 0m5.727s
+~/code/rspec-core
+result_comment
diff --git a/rspec-core/benchmarks/call_v_yield.rb b/rspec-core/benchmarks/call_v_yield.rb
new file mode 100644
index 0000000..f6b1bfb
--- /dev/null
+++ b/rspec-core/benchmarks/call_v_yield.rb
@@ -0,0 +1,81 @@
+require 'benchmark'
+
+n = 100_000
+
+def call_block(&block)
+  block.call
+end
+
+def yield_control
+  yield
+end
+
+Benchmark.benchmark do |bm|
+  puts "#{n} times - ruby #{RUBY_VERSION}"
+
+  puts
+  puts "eval"
+
+  3.times do
+    bm.report do
+      n.times do
+        eval("2 + 3")
+      end
+    end
+  end
+
+  puts
+  puts "call block"
+
+  3.times do
+    bm.report do
+      n.times do
+        call_block { 2 + 3 }
+      end
+    end
+  end
+
+  puts
+  puts "yield"
+
+  3.times do
+    bm.report do
+      n.times do
+        yield_control { 2 + 3 }
+      end
+    end
+  end
+
+  puts
+  puts "exec"
+
+  3.times do
+    bm.report do
+      n.times do
+        2 + 3
+      end
+    end
+  end
+end
+
+# 100000 times - ruby 1.9.3
+#
+# eval
+#    0.870000   0.010000   0.880000 (  0.877762)
+#    0.890000   0.000000   0.890000 (  0.891142)
+#    0.890000   0.000000   0.890000 (  0.896365)
+#
+# call block
+#    0.120000   0.010000   0.130000 (  0.136322)
+#    0.130000   0.010000   0.140000 (  0.138608)
+#    0.130000   0.000000   0.130000 (  0.129931)
+#
+# yield
+#    0.020000   0.000000   0.020000 (  0.020412)
+#    0.010000   0.000000   0.010000 (  0.017926)
+#    0.020000   0.000000   0.020000 (  0.025740)
+#
+# exec
+#    0.010000   0.000000   0.010000 (  0.009935)
+#    0.010000   0.000000   0.010000 (  0.011588)
+#    0.010000   0.000000   0.010000 (  0.010613)
diff --git a/rspec-core/benchmarks/capture_block_vs_yield.rb b/rspec-core/benchmarks/capture_block_vs_yield.rb
new file mode 100644
index 0000000..2705527
--- /dev/null
+++ b/rspec-core/benchmarks/capture_block_vs_yield.rb
@@ -0,0 +1,208 @@
+require 'benchmark/ips'
+
+def yield_control
+  yield
+end
+
+def capture_block_and_yield(&block)
+  yield
+end
+
+def capture_block_and_call(&block)
+  block.call
+end
+
+puts "Using the block directly"
+
+Benchmark.ips do |x|
+  x.report("yield                  ") do
+    yield_control { }
+  end
+
+  x.report("capture block and yield") do
+    capture_block_and_yield { }
+  end
+
+  x.report("capture block and call ") do
+    capture_block_and_call { }
+  end
+end
+
+puts "Forwarding the block to another method"
+
+def tap_with_yield
+  5.tap { |i| yield i }
+end
+
+def tap_with_forwarded_block(&block)
+  5.tap(&block)
+end
+
+Benchmark.ips do |x|
+  x.report("tap { |i| yield i }") do
+    tap_with_yield { |i| }
+  end
+
+  x.report("tap(&block)        ") do
+    tap_with_forwarded_block { |i| }
+  end
+end
+
+def yield_n_times(n)
+  n.times { yield }
+end
+
+def forward_block_to_n_times(n, &block)
+  n.times(&block)
+end
+
+def call_block_n_times(n, &block)
+  n.times { block.call }
+end
+
+[10, 25, 50, 100, 1000, 10000].each do |count|
+  puts "Invoking the block #{count} times"
+
+  Benchmark.ips do |x|
+    x.report("#{count}.times { yield }     ") do
+      yield_n_times(count) { }
+    end
+
+    x.report("#{count}.times(&block)       ") do
+      forward_block_to_n_times(count) { }
+    end
+
+    x.report("#{count}.times { block.call }") do
+      call_block_n_times(count) { }
+    end
+  end
+end
+
+__END__
+
+This benchmark demonstrates that capturing a block (e.g. `&block`) has
+a high constant cost, taking about 5x longer than a single `yield`
+(even if the block is never used!).
+
+However, fowarding a captured block can be faster than using `yield`
+if the block is used many times (the breakeven point is at about 20-25
+invocations), so it appears that he per-invocation cost of `yield`
+is higher than that of a captured-and-forwarded block.
+
+Note that there is no circumstance where using `block.call` is faster.
+
+See also `flat_map_vs_inject.rb`, which appears to contradict these
+results a little bit.
+
+Using the block directly
+Calculating -------------------------------------
+yield
+                        91.539k i/100ms
+capture block and yield
+                        50.945k i/100ms
+capture block and call
+                        50.923k i/100ms
+-------------------------------------------------
+yield
+                          4.757M (± 6.0%) i/s -     23.709M
+capture block and yield
+                          1.112M (±20.7%) i/s -      5.349M
+capture block and call
+                        964.475k (±20.3%) i/s -      4.634M
+Forwarding the block to another method
+Calculating -------------------------------------
+ tap { |i| yield i }    74.620k i/100ms
+ tap(&block)            51.382k i/100ms
+-------------------------------------------------
+ tap { |i| yield i }      3.213M (± 6.3%) i/s -     16.043M
+ tap(&block)            970.418k (±18.6%) i/s -      4.727M
+Invoking the block 10 times
+Calculating -------------------------------------
+10.times { yield }
+                        49.151k i/100ms
+10.times(&block)
+                        40.682k i/100ms
+10.times { block.call }
+                        27.576k i/100ms
+-------------------------------------------------
+10.times { yield }
+                        908.673k (± 4.9%) i/s -      4.571M
+10.times(&block)
+                        674.565k (±16.1%) i/s -      3.336M
+10.times { block.call }
+                        385.056k (±10.3%) i/s -      1.930M
+Invoking the block 25 times
+Calculating -------------------------------------
+25.times { yield }
+                        29.874k i/100ms
+25.times(&block)
+                        30.934k i/100ms
+25.times { block.call }
+                        17.119k i/100ms
+-------------------------------------------------
+25.times { yield }
+                        416.342k (± 3.6%) i/s -      2.091M
+25.times(&block)
+                        446.108k (±10.6%) i/s -      2.227M
+25.times { block.call }
+                        201.264k (± 7.2%) i/s -      1.010M
+Invoking the block 50 times
+Calculating -------------------------------------
+50.times { yield }
+                        17.690k i/100ms
+50.times(&block)
+                        21.760k i/100ms
+50.times { block.call }
+                         9.961k i/100ms
+-------------------------------------------------
+50.times { yield }
+                        216.195k (± 5.7%) i/s -      1.079M
+50.times(&block)
+                        280.217k (± 9.9%) i/s -      1.393M
+50.times { block.call }
+                        112.754k (± 5.6%) i/s -    567.777k
+Invoking the block 100 times
+Calculating -------------------------------------
+100.times { yield }
+                        10.143k i/100ms
+100.times(&block)
+                        13.688k i/100ms
+100.times { block.call }
+                         5.551k i/100ms
+-------------------------------------------------
+100.times { yield }
+                        111.700k (± 3.6%) i/s -    568.008k
+100.times(&block)
+                        163.638k (± 7.7%) i/s -    821.280k
+100.times { block.call }
+                         58.472k (± 5.6%) i/s -    294.203k
+Invoking the block 1000 times
+Calculating -------------------------------------
+1000.times { yield }
+                         1.113k i/100ms
+1000.times(&block)
+                         1.817k i/100ms
+1000.times { block.call }
+                       603.000  i/100ms
+-------------------------------------------------
+1000.times { yield }
+                         11.156k (± 8.4%) i/s -     56.763k
+1000.times(&block)
+                         18.551k (±10.1%) i/s -     92.667k
+1000.times { block.call }
+                          6.206k (± 3.5%) i/s -     31.356k
+Invoking the block 10000 times
+Calculating -------------------------------------
+10000.times { yield }
+                       113.000  i/100ms
+10000.times(&block)
+                       189.000  i/100ms
+10000.times { block.call }
+                        61.000  i/100ms
+-------------------------------------------------
+10000.times { yield }
+                          1.150k (± 3.6%) i/s -      5.763k
+10000.times(&block)
+                          1.896k (± 6.9%) i/s -      9.450k
+10000.times { block.call }
+                        624.401  (± 3.0%) i/s -      3.172k
diff --git a/rspec-core/benchmarks/check_inclusion.rb b/rspec-core/benchmarks/check_inclusion.rb
new file mode 100644
index 0000000..5f88872
--- /dev/null
+++ b/rspec-core/benchmarks/check_inclusion.rb
@@ -0,0 +1,125 @@
+require 'benchmark'
+
+n = 10_000
+
+num_modules = 1000
+
+class Foo; end
+modules = num_modules.times.map { Module.new }
+modules.each {|m| Foo.send(:include, m) }
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        Foo < modules.first
+      end
+    end
+  end
+end
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        Foo < modules.last
+      end
+    end
+  end
+end
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        Foo.included_modules.include?(modules.first)
+      end
+    end
+  end
+end
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        Foo.included_modules.include?(modules.last)
+      end
+    end
+  end
+end
+
+#### Ruby 1.9.3
+#
+# 100 modules
+# < modules.first
+  # 0.010000   0.000000   0.010000 (  0.005104)
+  # 0.000000   0.000000   0.000000 (  0.005114)
+  # 0.010000   0.000000   0.010000 (  0.005076)
+# < modules.last
+  # 0.000000   0.000000   0.000000 (  0.002180)
+  # 0.000000   0.000000   0.000000 (  0.002199)
+  # 0.000000   0.000000   0.000000 (  0.002189)
+# < included_modules.include?(modules.first)
+  # 0.110000   0.010000   0.120000 (  0.110062)
+  # 0.100000   0.000000   0.100000 (  0.105343)
+  # 0.100000   0.000000   0.100000 (  0.102770)
+# < included_modules.include?(modules.last)
+  # 0.050000   0.010000   0.060000 (  0.048520)
+  # 0.040000   0.000000   0.040000 (  0.049013)
+  # 0.050000   0.000000   0.050000 (  0.050668)
+
+# 1000 modules
+# < modules.first
+  # 0.080000   0.000000   0.080000 (  0.079460)
+  # 0.080000   0.000000   0.080000 (  0.078765)
+  # 0.080000   0.000000   0.080000 (  0.079560)
+# < modules.last
+  # 0.000000   0.000000   0.000000 (  0.002195)
+  # 0.000000   0.000000   0.000000 (  0.002201)
+  # 0.000000   0.000000   0.000000 (  0.002199)
+# < included_modules.include?(modules.first)
+  # 0.860000   0.010000   0.870000 (  0.887684)
+  # 0.870000   0.000000   0.870000 (  0.875158)
+  # 0.870000   0.000000   0.870000 (  0.879216)
+# < included_modules.include?(modules.last)
+  # 0.340000   0.000000   0.340000 (  0.344011)
+  # 0.350000   0.000000   0.350000 (  0.346277)
+  # 0.330000   0.000000   0.330000 (  0.335607)
+
+#### Ruby 1.8.7
+#
+# 100 modules
+# < modules.first
+  # 0.010000   0.000000   0.010000 (  0.007132)
+  # 0.010000   0.000000   0.010000 (  0.006869)
+  # 0.000000   0.000000   0.000000 (  0.005334)
+# < modules.last
+  # 0.010000   0.000000   0.010000 (  0.003438)
+  # 0.000000   0.000000   0.000000 (  0.003454)
+  # 0.000000   0.000000   0.000000 (  0.003408)
+# < included_modules.include?(modules.first)
+  # 0.110000   0.010000   0.120000 (  0.113255)
+  # 0.110000   0.000000   0.110000 (  0.112880)
+  # 0.110000   0.000000   0.110000 (  0.121003)
+# < included_modules.include?(modules.last)
+  # 0.040000   0.010000   0.050000 (  0.040736)
+  # 0.040000   0.000000   0.040000 (  0.039609)
+  # 0.030000   0.000000   0.030000 (  0.039888)
+
+# 1000 modules
+# < modules.first
+  # 0.040000   0.000000   0.040000 (  0.044124)
+  # 0.050000   0.000000   0.050000 (  0.046110)
+  # 0.040000   0.000000   0.040000 (  0.042603)
+# < modules.last
+  # 0.000000   0.000000   0.000000 (  0.003405)
+  # 0.010000   0.000000   0.010000 (  0.005510)
+  # 0.000000   0.000000   0.000000 (  0.003562)
+# < included_modules.include?(modules.first)
+  # 0.990000   0.000000   0.990000 (  1.096331)
+  # 1.030000   0.010000   1.040000 (  1.047791)
+  # 0.990000   0.000000   0.990000 (  1.019169)
+# < included_modules.include?(modules.last)
+  # 0.260000   0.000000   0.260000 (  0.265306)
+  # 0.270000   0.000000   0.270000 (  0.311985)
+  # 0.270000   0.000000   0.270000 (  0.277936)
diff --git a/rspec-core/benchmarks/define_method_v_attr_reader_v_def.rb b/rspec-core/benchmarks/define_method_v_attr_reader_v_def.rb
new file mode 100644
index 0000000..d7b8ab2
--- /dev/null
+++ b/rspec-core/benchmarks/define_method_v_attr_reader_v_def.rb
@@ -0,0 +1,81 @@
+require 'benchmark'
+
+n = 1_000_000
+
+puts "each sample runs #{n} times"
+puts
+
+class Foo
+  define_method :foo do
+    @foo
+  end
+
+  attr_reader :bar
+
+  def initialize
+    @foo = 'foo'
+    @bar = 'bar'
+    @baz = 'baz'
+  end
+
+  def baz
+    @baz
+  end
+end
+
+foo = Foo.new
+
+puts "define_method"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        foo.foo
+      end
+    end
+  end
+end
+
+puts
+puts "attr_reader"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        foo.bar
+      end
+    end
+  end
+end
+
+puts
+puts "def"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        foo.baz
+      end
+    end
+  end
+end
+
+# $ ruby -v
+# ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.0.0]
+# $ ruby benchmarks/define_method_v_attr_reader_v_def.rb
+# each sample runs 1000000 times
+#
+# define_method
+#   0.250000   0.000000   0.250000 (  0.251552)
+#   0.250000   0.000000   0.250000 (  0.261506)
+#   0.250000   0.000000   0.250000 (  0.247398)
+#
+# attr_reader
+#   0.140000   0.000000   0.140000 (  0.141782)
+#   0.140000   0.000000   0.140000 (  0.142411)
+#   0.140000   0.000000   0.140000 (  0.145876)
+#
+# def
+#   0.160000   0.000000   0.160000 (  0.153261)
+#   0.150000   0.000000   0.150000 (  0.158096)
+#   0.150000   0.000000   0.150000 (  0.149472)
diff --git a/rspec-core/benchmarks/eager_vs_lazy_metadata.rb b/rspec-core/benchmarks/eager_vs_lazy_metadata.rb
new file mode 100644
index 0000000..05c3620
--- /dev/null
+++ b/rspec-core/benchmarks/eager_vs_lazy_metadata.rb
@@ -0,0 +1,126 @@
+require 'benchmark'
+
+# preload rspec since we don't want to benchmark that.
+require 'rspec/core'
+require 'rspec/mocks'
+require 'rspec/expectations'
+
+def run_benchmark(description, *args)
+  Benchmark.benchmark do |bm|
+    3.times.each do
+      bm.report(description) do
+        pid = fork do
+          RSpec::Core::Runner.run([
+            # This file defines 16250 examples at various levels of nesting.
+            "./benchmarks/eager_vs_lazy_metadata/define_examples.rb",
+            *args
+          ], StringIO.new, StringIO.new)
+
+          exit!
+        end
+
+        # writeme.close
+        Process.wait(pid)
+      end
+    end
+  end
+end
+
+puts "#{RUBY_VERSION} - #{RSpec::Core::Metadata < Hash ? "lazy" : "eager"}"
+
+run_benchmark("progress formatter, all", "-fp")
+run_benchmark("documentation formatter, all", "-fd")
+run_benchmark("progress formatter, filtering by example", "-fp", "-e", "nested")
+run_benchmark("documentation formatter, filtering by example", "-fd", "-e", "nested")
+
+__END__
+
+On 2.1, precomputing metadata appears to be about 15% faster.
+
+2.1.0 - eager
+progress formatter, all  0.000000   0.000000   1.690000 (  1.700527)
+progress formatter, all  0.000000   0.000000   1.710000 (  1.712091)
+progress formatter, all  0.000000   0.000000   1.690000 (  1.694437)
+documentation formatter, all  0.000000   0.000000   1.740000 (  1.752185)
+documentation formatter, all  0.000000   0.000000   1.740000 (  1.743691)
+documentation formatter, all  0.000000   0.010000   1.760000 (  1.752427)
+progress formatter, filtering by example  0.000000   0.000000   1.710000 (  1.712782)
+progress formatter, filtering by example  0.000000   0.000000   1.690000 (  1.695519)
+progress formatter, filtering by example  0.000000   0.000000   1.680000 (  1.688278)
+documentation formatter, filtering by example  0.000000   0.000000   1.740000 (  1.734581)
+documentation formatter, filtering by example  0.000000   0.000000   1.720000 (  1.730275)
+documentation formatter, filtering by example  0.000000   0.000000   1.730000 (  1.729879)
+
+2.1.0 - lazy
+progress formatter, all  0.000000   0.010000   2.020000 (  2.021899)
+progress formatter, all  0.000000   0.000000   2.010000 (  2.013904)
+progress formatter, all  0.000000   0.000000   1.990000 (  2.004857)
+documentation formatter, all  0.000000   0.000000   2.120000 (  2.119586)
+documentation formatter, all  0.000000   0.000000   2.120000 (  2.122598)
+documentation formatter, all  0.000000   0.000000   2.110000 (  2.115573)
+progress formatter, filtering by example  0.000000   0.000000   2.080000 (  2.081120)
+progress formatter, filtering by example  0.000000   0.000000   2.050000 (  2.066418)
+progress formatter, filtering by example  0.000000   0.000000   2.090000 (  2.085655)
+documentation formatter, filtering by example  0.000000   0.010000   2.160000 (  2.166207)
+documentation formatter, filtering by example  0.000000   0.000000   2.200000 (  2.196856)
+documentation formatter, filtering by example  0.000000   0.000000   2.170000 (  2.172799)
+
+On 2.0, precomputing metadata appears to be about 20% faster.
+
+2.0.0 - eager
+progress formatter, all  0.000000   0.000000   1.720000 (  1.730478)
+progress formatter, all  0.000000   0.000000   1.710000 (  1.708679)
+progress formatter, all  0.000000   0.000000   1.750000 (  1.753906)
+documentation formatter, all  0.000000   0.000000   1.790000 (  1.804745)
+documentation formatter, all  0.010000   0.010000   1.830000 (  1.805737)
+documentation formatter, all  0.000000   0.000000   1.780000 (  1.802866)
+progress formatter, filtering by example  0.000000   0.000000   1.720000 (  1.714562)
+progress formatter, filtering by example  0.000000   0.000000   1.660000 (  1.663136)
+progress formatter, filtering by example  0.000000   0.000000   1.710000 (  1.716405)
+documentation formatter, filtering by example  0.000000   0.000000   1.760000 (  1.756188)
+documentation formatter, filtering by example  0.000000   0.000000   1.760000 (  1.779646)
+documentation formatter, filtering by example  0.000000   0.010000   1.780000 (  1.766562)
+
+2.0.0 - lazy
+progress formatter, all  0.000000   0.000000   2.140000 (  2.144684)
+progress formatter, all  0.000000   0.000000   2.140000 (  2.152171)
+progress formatter, all  0.000000   0.000000   2.150000 (  2.156945)
+documentation formatter, all  0.000000   0.000000   2.270000 (  2.276520)
+documentation formatter, all  0.000000   0.000000   2.270000 (  2.271053)
+documentation formatter, all  0.000000   0.000000   2.280000 (  2.274769)
+progress formatter, filtering by example  0.000000   0.000000   2.210000 (  2.222937)
+progress formatter, filtering by example  0.000000   0.000000   2.190000 (  2.195851)
+progress formatter, filtering by example  0.000000   0.000000   2.240000 (  2.251092)
+documentation formatter, filtering by example  0.000000   0.010000   2.380000 (  2.368707)
+documentation formatter, filtering by example  0.000000   0.000000   2.390000 (  2.405561)
+documentation formatter, filtering by example  0.000000   0.000000   2.430000 (  2.422848)
+
+On 1.9.3 it appears to be a wash.
+
+1.9.3 - eager
+progress formatter, all  0.000000   0.000000   1.860000 (  1.862991)
+progress formatter, all  0.000000   0.000000   1.930000 (  1.940352)
+progress formatter, all  0.000000   0.010000   1.860000 (  1.854856)
+documentation formatter, all  0.000000   0.000000   1.900000 (  1.912110)
+documentation formatter, all  0.000000   0.000000   2.000000 (  1.998096)
+documentation formatter, all  0.000000   0.000000   1.910000 (  1.914563)
+progress formatter, filtering by example  0.000000   0.000000   1.800000 (  1.800767)
+progress formatter, filtering by example  0.000000   0.000000   1.900000 (  1.918205)
+progress formatter, filtering by example  0.000000   0.000000   1.830000 (  1.824907)
+documentation formatter, filtering by example  0.000000   0.000000   1.850000 (  1.855187)
+documentation formatter, filtering by example  0.000000   0.000000   1.940000 (  1.945985)
+documentation formatter, filtering by example  0.000000   0.010000   1.880000 (  1.879237)
+
+1.9.3 - lazy
+progress formatter, all  0.000000   0.000000   1.950000 (  1.953861)
+progress formatter, all  0.000000   0.000000   1.840000 (  1.848092)
+progress formatter, all  0.000000   0.000000   1.920000 (  1.930265)
+documentation formatter, all  0.000000   0.000000   1.920000 (  1.922012)
+documentation formatter, all  0.000000   0.000000   2.010000 (  2.012511)
+documentation formatter, all  0.000000   0.000000   1.920000 (  1.921090)
+progress formatter, filtering by example  0.000000   0.010000   1.990000 (  1.986591)
+progress formatter, filtering by example  0.000000   0.000000   1.990000 (  1.986991)
+progress formatter, filtering by example  0.000000   0.000000   1.990000 (  1.991256)
+documentation formatter, filtering by example  0.000000   0.000000   2.070000 (  2.080637)
+documentation formatter, filtering by example  0.000000   0.000000   2.030000 (  2.041768)
+documentation formatter, filtering by example  0.000000   0.000000   1.970000 (  1.974151)
diff --git a/rspec-core/benchmarks/eager_vs_lazy_metadata/define_examples.rb b/rspec-core/benchmarks/eager_vs_lazy_metadata/define_examples.rb
new file mode 100644
index 0000000..932c2ac
--- /dev/null
+++ b/rspec-core/benchmarks/eager_vs_lazy_metadata/define_examples.rb
@@ -0,0 +1,22 @@
+top_level_example_groups = 25
+examples = 25
+nested_groups = 25
+nested_examples = 25
+
+top_level_example_groups.times do |tlg|
+  RSpec.describe "Top level group #{tlg}", :foo => 3 do
+
+    examples.times do |e|
+      it("example #{e}", :bar => 4) { }
+    end
+
+    nested_groups.times do |ng|
+      context "nested #{ng}" do
+        nested_examples.times do |ne|
+          it("example #{ne}") { }
+        end
+      end
+    end
+  end
+end
+
diff --git a/rspec-core/benchmarks/filter_object.rb b/rspec-core/benchmarks/filter_object.rb
new file mode 100644
index 0000000..c0d9267
--- /dev/null
+++ b/rspec-core/benchmarks/filter_object.rb
@@ -0,0 +1,35 @@
+require 'benchmark'
+require 'tmpdir'
+
+path = File.join(Dir.tmpdir, "benchmark_example_spec.rb")
+
+File.open(path, 'w') do |f|
+  f.puts %q|describe "something" do|
+  100.times do |n|
+    f.puts <<-TEXT
+  it "does something #{n}", :focus => true do
+  end
+TEXT
+  end
+  100.times do |n|
+    f.puts <<-TEXT
+  it "does something else #{n}" do
+  end
+TEXT
+  end
+  f.puts %q|end|
+end
+
+n = 1
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        `bin/rspec --tag focus #{path}`
+      end
+    end
+  end
+end
+
+File.delete(path)
diff --git a/rspec-core/benchmarks/flat_map_vs_inject.rb b/rspec-core/benchmarks/flat_map_vs_inject.rb
new file mode 100644
index 0000000..6a99d19
--- /dev/null
+++ b/rspec-core/benchmarks/flat_map_vs_inject.rb
@@ -0,0 +1,55 @@
+require 'benchmark/ips'
+
+words = %w[ foo bar bazz big small medium large tiny less more good bad mediocre ]
+
+def flat_map_using_yield(array)
+  array.flat_map { |item| yield item }
+end
+
+def flat_map_using_block(array, &block)
+  array.flat_map(&block)
+end
+
+Benchmark.ips do |x|
+  x.report("flat_map") do
+    words.flat_map(&:codepoints)
+  end
+
+  x.report("inject (+)") do
+    words.inject([]) { |a, w| a + w.codepoints }
+  end
+
+  x.report("inject (concat)") do
+    words.inject([]) { |a, w| a.concat w.codepoints }
+  end
+
+  x.report("flat_map_using_yield") do
+    flat_map_using_yield(words, &:codepoints)
+  end
+
+  x.report("flat_map_using_block") do
+    flat_map_using_block(words, &:codepoints)
+  end
+end
+
+__END__
+
+Surprisingly, `flat_map(&block)` appears to be faster than
+`flat_map { yield }` in spite of the fact that our array here
+is smaller than the break-even point of 20-25 measured in the
+`capture_block_vs_yield.rb` benchmark. In fact, the forwaded-block
+version remains faster in my benchmarks here no matter how small
+I shrink the `words` array. I'm not sure why!
+
+Calculating -------------------------------------
+            flat_map    10.594k i/100ms
+          inject (+)     8.357k i/100ms
+     inject (concat)    10.404k i/100ms
+flat_map_using_yield    10.081k i/100ms
+flat_map_using_block    11.683k i/100ms
+-------------------------------------------------
+            flat_map    136.442k (±10.4%) i/s -    678.016k
+          inject (+)     98.024k (± 9.7%) i/s -    493.063k
+     inject (concat)    119.822k (±10.5%) i/s -    593.028k
+flat_map_using_yield    112.284k (± 9.7%) i/s -    564.536k
+flat_map_using_block    134.533k (± 6.3%) i/s -    677.614k
diff --git a/rspec-core/benchmarks/index_v_take_while.rb b/rspec-core/benchmarks/index_v_take_while.rb
new file mode 100644
index 0000000..5c1a311
--- /dev/null
+++ b/rspec-core/benchmarks/index_v_take_while.rb
@@ -0,0 +1,47 @@
+require 'benchmark'
+
+n = 10000
+
+list = 1.upto(10).to_a
+
+Benchmark.benchmark do |bm|
+  puts "take_while"
+  3.times do
+    bm.report do
+      n.times do
+        list.
+          take_while {|i| i < 6}.
+          map {|i| i}.
+          compact
+      end
+    end
+  end
+
+  puts
+
+  puts "list[0,n]"
+  3.times do
+    bm.report do
+      n.times do
+        if index = list.index(6)
+          list[0, index].map {|i| i.to_s}
+        else
+          list.map {|i| i}.compact
+        end
+      end
+    end
+  end
+end
+
+__END__
+
+ruby benchmarks/index_v_take_while.rb
+take_while
+   0.020000   0.000000   0.020000 (  0.020005)
+   0.010000   0.000000   0.010000 (  0.015907)
+   0.010000   0.000000   0.010000 (  0.015962)
+
+list[0,n]
+   0.020000   0.000000   0.020000 (  0.023561)
+   0.020000   0.000000   0.020000 (  0.018812)
+   0.030000   0.000000   0.030000 (  0.022389)
diff --git a/rspec-core/benchmarks/map_then_flatten_vs_flat_map_benchmarks.rb b/rspec-core/benchmarks/map_then_flatten_vs_flat_map_benchmarks.rb
new file mode 100644
index 0000000..ccdbc6e
--- /dev/null
+++ b/rspec-core/benchmarks/map_then_flatten_vs_flat_map_benchmarks.rb
@@ -0,0 +1,94 @@
+require 'benchmark'
+
+$n = 10000
+size = 100
+
+puts "size: #{size}"
+puts
+
+def report
+  reals = []
+  Benchmark.benchmark do |bm|
+    3.times do
+      reals << bm.report { $n.times { yield } }.real
+    end
+  end
+
+  reals.inject(&:+) / reals.count
+end
+
+avgs = []
+
+puts "map then flatten"
+avgs << report {
+  (1..size).
+    map {|n| [n]}.
+    flatten
+}
+
+puts
+
+puts "flat_map"
+avgs << report {
+  (1..size).
+    flat_map {|n| [n]}
+}
+
+puts avgs
+if avgs[0] < avgs[1]
+  puts "map then flatten faster by #{((1.0 - avgs[0]/avgs[1]) * 100).round(2)} %"
+else
+  puts "flat_map faster by #{((1.0 - avgs[1]/avgs[0]) * 100).round(2)} %"
+end
+
+__END__
+
+for each size (10, 100, 1000) showing smallest diff
+  between map-then-flatten and flat_map in at least
+  5 runs
+
+size: 10
+
+map then flatten
+   0.550000   0.000000   0.550000 (  0.547897)
+   0.570000   0.000000   0.570000 (  0.565139)
+   0.550000   0.000000   0.550000 (  0.557421)
+
+flat_map
+   0.320000   0.000000   0.320000 (  0.316801)
+   0.320000   0.010000   0.330000 (  0.325373)
+   0.330000   0.000000   0.330000 (  0.325169)
+
+flat_map faster by 42.09 %
+
+**********************************************
+
+size: 100
+
+map then flatten
+   0.390000   0.000000   0.390000 (  0.387307)
+   0.390000   0.000000   0.390000 (  0.387630)
+   0.380000   0.000000   0.380000 (  0.389421)
+
+flat_map
+   0.250000   0.000000   0.250000 (  0.259444)
+   0.270000   0.000000   0.270000 (  0.261972)
+   0.250000   0.000000   0.250000 (  0.252584)
+
+flat_map faster by 33.53 %
+
+**********************************************
+
+size: 1000
+
+map then flatten
+   0.380000   0.000000   0.380000 (  0.382788)
+   0.380000   0.000000   0.380000 (  0.372447)
+   0.370000   0.000000   0.370000 (  0.370065)
+
+flat_map
+   0.240000   0.000000   0.240000 (  0.240357)
+   0.240000   0.000000   0.240000 (  0.242325)
+   0.240000   0.000000   0.240000 (  0.240985)
+
+flat_map faster by 35.69 %
diff --git a/rspec-core/benchmarks/module_inclusion_filtering.rb b/rspec-core/benchmarks/module_inclusion_filtering.rb
new file mode 100644
index 0000000..eaeb5f0
--- /dev/null
+++ b/rspec-core/benchmarks/module_inclusion_filtering.rb
@@ -0,0 +1,89 @@
+require_relative "../bundle/bundler/setup" # configures load paths
+require 'rspec/core'
+
+class << RSpec
+  attr_writer :world
+end
+
+# Here we are restoring the old implementation of `configure_group`, so that
+# we can toggle the new vs old implementation in the benchmark by aliasing it.
+module RSpecConfigurationOverrides
+  def initialize(*args)
+    super
+    @include_extend_or_prepend_modules = []
+  end
+
+  def include(mod, *filters)
+    meta = RSpec::Core::Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
+    @include_extend_or_prepend_modules << [:include, mod, meta]
+    super
+  end
+
+  def old_configure_group(group)
+    @include_extend_or_prepend_modules.each do |include_extend_or_prepend, mod, filters|
+      next unless filters.empty? || RSpec::Core::MetadataFilter.apply?(:any?, filters, group.metadata)
+      __send__("safe_#{include_extend_or_prepend}", mod, group)
+    end
+  end
+
+  def self.prepare_implementation(prefix)
+    RSpec.world = RSpec::Core::World.new # clear our state
+    RSpec::Core::Configuration.class_eval do
+      alias_method :configure_group, :"#{prefix}_configure_group"
+    end
+  end
+end
+
+RSpec::Core::Configuration.class_eval do
+  prepend RSpecConfigurationOverrides
+  alias new_configure_group configure_group
+end
+
+RSpec.configure do |c|
+  50.times { c.include Module.new, :include_it }
+end
+
+require 'benchmark/ips'
+
+Benchmark.ips do |x|
+  x.report("Old linear search: non-matching metadata") do |times|
+    RSpecConfigurationOverrides.prepare_implementation(:old)
+    times.times { |i| RSpec.describe "Old linear search: non-matching metadata #{i}" }
+  end
+
+  x.report("New memoized search: non-matching metadata") do |times|
+    RSpecConfigurationOverrides.prepare_implementation(:new)
+    times.times { |i| RSpec.describe "New memoized search: non-matching metadata #{i}" }
+  end
+
+  x.report("Old linear search: matching metadata") do |times|
+    RSpecConfigurationOverrides.prepare_implementation(:old)
+    times.times { |i| RSpec.describe "Old linear search: matching metadata #{i}", :include_it }
+  end
+
+  x.report("New memoized search: matching metadata") do |times|
+    RSpecConfigurationOverrides.prepare_implementation(:new)
+    times.times { |i| RSpec.describe "New memoized search: matching metadata #{i}", :include_it }
+  end
+end
+
+__END__
+
+Calculating -------------------------------------
+Old linear search: non-matching metadata
+                        86.000  i/100ms
+New memoized search: non-matching metadata
+                        93.000  i/100ms
+Old linear search: matching metadata
+                        79.000  i/100ms
+New memoized search: matching metadata
+                        90.000  i/100ms
+-------------------------------------------------
+Old linear search: non-matching metadata
+                        884.109  (±61.9%) i/s -      3.268k
+New memoized search: non-matching metadata
+                          1.099k (±81.2%) i/s -      3.441k
+Old linear search: matching metadata
+                        822.348  (±57.5%) i/s -      3.081k
+New memoized search: matching metadata
+                          1.116k (±76.6%) i/s -      3.510k
diff --git a/rspec-core/benchmarks/precalculate_absolute_file_path_or_not.rb b/rspec-core/benchmarks/precalculate_absolute_file_path_or_not.rb
new file mode 100644
index 0000000..3810bce
--- /dev/null
+++ b/rspec-core/benchmarks/precalculate_absolute_file_path_or_not.rb
@@ -0,0 +1,29 @@
+require 'benchmark/ips'
+
+metadata = { :file_path => "some/path.rb" }
+meta_with_absolute = metadata.merge(:absolute_file_path => File.expand_path(metadata[:file_path]))
+
+Benchmark.ips do |x|
+  x.report("fetch absolute path from hash") do
+    meta_with_absolute[:absolute_file_path]
+  end
+
+  x.report("calculate absolute path") do
+    File.expand_path(metadata[:file_path])
+  end
+end
+
+__END__
+
+Precalculating the absolute file path is much, much faster!
+
+Calculating -------------------------------------
+fetch absolute path from hash
+                       102.164k i/100ms
+calculate absolute path
+                         9.331k i/100ms
+-------------------------------------------------
+fetch absolute path from hash
+                          7.091M (±11.6%) i/s -     34.736M
+calculate absolute path
+                        113.141k (± 8.6%) i/s -    569.191k
diff --git a/rspec-core/benchmarks/require_relative_v_require.rb b/rspec-core/benchmarks/require_relative_v_require.rb
new file mode 100644
index 0000000..04a5baf
--- /dev/null
+++ b/rspec-core/benchmarks/require_relative_v_require.rb
@@ -0,0 +1,75 @@
+require 'benchmark'
+
+n = 20
+
+Benchmark.benchmark do |bm|
+  3.times.each do
+    bm.report do
+      n.times do
+        pid = fork do
+          require 'rspec/core'
+        end
+        Process.wait(pid)
+      end
+    end
+  end
+end
+
+# ###################################
+# Ruby 1.9.3 - 3 x 20
+# require
+# $ bundle exec ruby benchmarks/require_relative_v_require.rb
+#    0.000000   0.020000   2.540000 (  2.568784)
+#    0.000000   0.010000   2.550000 (  2.580621)
+#    0.000000   0.020000   2.510000 (  2.548631)
+#
+# require_relative
+# $ bundle exec ruby benchmarks/require_relative_v_require.rb
+#    0.000000   0.010000   2.220000 (  2.288229)
+#    0.000000   0.010000   2.250000 (  2.289886)
+#    0.000000   0.020000   2.260000 (  2.296639)
+#
+# roughly 12% improvement
+#
+# ###################################
+#
+# Ruby 1.8.7 - 3 x 20
+# before change (using require, but no conditional)
+# $ bundle exec ruby benchmarks/require_relative_v_require.rb
+#   0.000000   0.010000   1.210000 (  1.242291)
+#   0.000000   0.010000   1.230000 (  1.259518)
+#   0.000000   0.010000   1.230000 (  1.250333)
+#
+# after change (still using require, but adding conditional)
+# $ bundle exec ruby benchmarks/require_relative_v_require.rb
+#   0.000000   0.010000   1.200000 (  1.227249)
+#   0.000000   0.010000   1.230000 (  1.257012)
+#   0.000000   0.010000   1.230000 (  1.259278)
+#
+# virtually no penalty
+#
+# ###################################
+
+__END__
+
+Ruby 2.0:
+
+➜  rspec-core git:(benchmark-require-relative) REQUIRE_RELATIVE=1 bundle exec ruby benchmarks/require_relative_v_require.rb
+   0.000000   0.030000   1.470000 (  1.481949)
+   0.000000   0.020000   1.440000 (  1.462620)
+   0.000000   0.020000   1.470000 (  1.491825)
+➜  rspec-core git:(benchmark-require-relative) bundle exec ruby benchmarks/require_relative_v_require.rb
+   0.000000   0.010000   1.510000 (  1.549906)
+   0.000000   0.010000   1.530000 (  1.546252)
+   0.000000   0.020000   1.510000 (  1.531644)
+
+Ruby 2.1:
+
+➜  rspec-core git:(benchmark-require-relative) bundle exec ruby benchmarks/require_relative_v_require.rb
+   0.000000   0.020000   1.570000 (  1.613217)
+   0.000000   0.020000   1.600000 (  1.618540)
+   0.010000   0.020000   1.570000 (  1.608205)
+➜  rspec-core git:(benchmark-require-relative) REQUIRE_RELATIVE=1 bundle exec ruby benchmarks/require_relative_v_require.rb
+   0.000000   0.020000   1.480000 (  1.515131)
+   0.000000   0.010000   1.480000 (  1.527766)
+   0.000000   0.020000   1.490000 (  1.515631)
diff --git a/rspec-core/benchmarks/respond_to_v_defined.rb b/rspec-core/benchmarks/respond_to_v_defined.rb
new file mode 100644
index 0000000..5846a31
--- /dev/null
+++ b/rspec-core/benchmarks/respond_to_v_defined.rb
@@ -0,0 +1,72 @@
+require 'benchmark'
+
+n = 1_000_000
+
+puts "Kernel.respond_to?(:warn)"
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+       Kernel.respond_to?(:warn)
+      end
+    end
+  end
+end
+
+puts "defined?(warn)"
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        defined?(warn)
+      end
+    end
+  end
+end
+
+puts "Kernel.respond_to?(:foo)"
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        Kernel.respond_to?(:foo)
+      end
+    end
+  end
+end
+
+puts "defined?(foo)"
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        defined?(foo)
+      end
+    end
+  end
+end
+
+# $ ruby benchmarks/respond_to_v_defined.rb
+# Kernel.respond_to?(:warn)
+#    0.190000   0.000000   0.190000 (  0.206502)
+#    0.190000   0.000000   0.190000 (  0.197547)
+#    0.190000   0.000000   0.190000 (  0.189731)
+# defined?(warn)
+#    0.190000   0.000000   0.190000 (  0.187334)
+#    0.180000   0.000000   0.180000 (  0.201078)
+#    0.190000   0.000000   0.190000 (  0.202295)
+# Kernel.respond_to?(:foo)
+#    0.250000   0.010000   0.260000 (  0.255003)
+#    0.240000   0.000000   0.240000 (  0.247376)
+#    0.250000   0.000000   0.250000 (  0.251196)
+# defined?(foo)
+#    0.100000   0.000000   0.100000 (  0.104748)
+#    0.110000   0.000000   0.110000 (  0.107250)
+#    0.110000   0.000000   0.110000 (  0.107990)
+#
+# defined is consistently faster, but it takes 1,000,000 x to have a meaningful
+# diff
diff --git a/rspec-core/benchmarks/several_regexps_v_one_big_one.rb b/rspec-core/benchmarks/several_regexps_v_one_big_one.rb
new file mode 100644
index 0000000..09dfcf9
--- /dev/null
+++ b/rspec-core/benchmarks/several_regexps_v_one_big_one.rb
@@ -0,0 +1,86 @@
+require 'benchmark'
+
+$t = 3
+$n = 100000
+
+def report(header)
+  puts header
+  reals = []
+  Benchmark.bm do |bm|
+    $t.times do
+      reals << bm.report { $n.times { yield } }.real
+    end
+  end
+
+  [header, (reals.inject(&:+) / reals.count).round(5)]
+end
+
+multi = [
+  /\/lib\d*\/ruby\//,
+  /org\/jruby\//,
+  /bin\//,
+  %r|/gems/|,
+  /lib\/rspec\/(core|expectations|matchers|mocks)/
+]
+
+union = [Regexp.union(multi)]
+
+avgs = []
+
+avgs << report("multi w/ match") {
+  multi.any? {|e| e =~ "lib/rspec/core"}
+}
+
+avgs << report("union w/ match") {
+  union.any? {|e| e =~ "lib/rspec/core"}
+}
+
+avgs << report("multi w/ no match") {
+  multi.any? {|e| e =~ "foo/bar"}
+}
+
+avgs << report("union w/ no match") {
+  union.any? {|e| e =~ "foo/bar"}
+}
+
+puts
+
+avgs.each do |header, val|
+  puts header, val
+  puts
+end
+
+__END__
+
+multi w/ match
+       user     system      total        real
+   0.400000   0.000000   0.400000 (  0.405063)
+   0.410000   0.000000   0.410000 (  0.402778)
+   0.430000   0.000000   0.430000 (  0.435447)
+union w/ match
+       user     system      total        real
+   0.130000   0.000000   0.130000 (  0.127526)
+   0.130000   0.000000   0.130000 (  0.135529)
+   0.130000   0.000000   0.130000 (  0.127866)
+multi w/ no match
+       user     system      total        real
+   0.320000   0.000000   0.320000 (  0.318921)
+   0.330000   0.000000   0.330000 (  0.328375)
+   0.340000   0.000000   0.340000 (  0.341230)
+union w/ no match
+       user     system      total        real
+   0.170000   0.000000   0.170000 (  0.175144)
+   0.170000   0.000000   0.170000 (  0.168816)
+   0.170000   0.000000   0.170000 (  0.168362)
+
+multi w/ match
+0.41443
+
+union w/ match
+0.13031
+
+multi w/ no match
+0.32951
+
+union w/ no match
+0.17077
diff --git a/rspec-core/benchmarks/singleton_example_groups/helper.rb b/rspec-core/benchmarks/singleton_example_groups/helper.rb
new file mode 100644
index 0000000..8f543c1
--- /dev/null
+++ b/rspec-core/benchmarks/singleton_example_groups/helper.rb
@@ -0,0 +1,120 @@
+require_relative "../../bundle/bundler/setup" # configures load paths
+require 'rspec/core'
+require 'stackprof'
+
+class << RSpec
+  attr_writer :world
+end
+
+RSpec::Core::Example.class_eval do
+  alias_method :new_with_around_and_singleton_context_hooks, :with_around_and_singleton_context_hooks
+  alias_method :old_with_around_and_singleton_context_hooks, :with_around_example_hooks
+end
+
+RSpec::Core::Hooks::HookCollections.class_eval do
+  def old_register_global_singleton_context_hooks(*)
+    # no-op: this method didn't exist before
+  end
+  alias_method :new_register_global_singleton_context_hooks, :register_global_singleton_context_hooks
+end
+
+RSpec::Core::Configuration.class_eval do
+  def old_configure_example(*)
+    # no-op: this method didn't exist before
+  end
+  alias_method :new_configure_example, :configure_example
+end
+
+RSpec.configure do |c|
+  c.output_stream = StringIO.new
+end
+
+require 'benchmark/ips'
+
+class BenchmarkHelpers
+  def self.prepare_implementation(prefix)
+    RSpec.world = RSpec::Core::World.new # clear our state
+    RSpec::Core::Example.__send__ :alias_method, :with_around_and_singleton_context_hooks, :"#{prefix}_with_around_and_singleton_context_hooks"
+    RSpec::Core::Hooks::HookCollections.__send__ :alias_method, :register_global_singleton_context_hooks, :"#{prefix}_register_global_singleton_context_hooks"
+    RSpec::Core::Configuration.__send__ :alias_method, :configure_example, :"#{prefix}_configure_example"
+  end
+
+  @@runner = RSpec::Core::Runner.new(RSpec::Core::ConfigurationOptions.new([]))
+  def self.define_and_run_examples(desc, count, group_meta: {}, example_meta: {})
+    groups = count.times.map do |i|
+      RSpec.describe "Group #{desc} #{i}", group_meta do
+        10.times { |j| example("ex #{j}", example_meta) { } }
+      end
+    end
+
+    @@runner.run_specs(groups)
+  end
+
+  def self.profile(count, meta = { example_meta: { apply_it: true } })
+    [:new, :old].map do |prefix|
+      prepare_implementation(prefix)
+
+      results = StackProf.run(mode: :cpu) do
+        define_and_run_examples("No match/#{prefix}", count, meta)
+      end
+
+      format_profile_results(results, prefix)
+    end
+  end
+
+  def self.format_profile_results(results, prefix)
+    File.open("tmp/#{prefix}_stack_prof_results.txt", "w") do |f|
+      StackProf::Report.new(results).print_text(false, nil, f)
+    end
+    system "open tmp/#{prefix}_stack_prof_results.txt"
+
+    File.open("tmp/#{prefix}_stack_prof_results.graphviz", "w") do |f|
+      StackProf::Report.new(results).print_graphviz(nil, f)
+    end
+
+    system "dot tmp/#{prefix}_stack_prof_results.graphviz -Tpdf > tmp/#{prefix}_stack_prof_results.pdf"
+    system "open tmp/#{prefix}_stack_prof_results.pdf"
+  end
+
+  def self.run_benchmarks
+    Benchmark.ips do |x|
+      implementations = { :old => "without", :new => "with" }
+      # Historically, many of our benchmarks have initially been order-sensitive,
+      # where whichever implementation went first got favored because defining
+      # more groups (or whatever) would cause things to slow down. To easily
+      # check if we're having those problems, you can pass REVERSE=1 to try
+      # it out in the opposite order.
+      implementations = implementations.to_a.reverse.to_h if ENV['REVERSE']
+
+      implementations.each do |prefix, description|
+        x.report("No match -- #{description} singleton group support") do |times|
+          prepare_implementation(prefix)
+          define_and_run_examples("No match/#{description}", times)
+        end
+      end
+
+      implementations.each do |prefix, description|
+        x.report("Example match -- #{description} singleton group support") do |times|
+          prepare_implementation(prefix)
+          define_and_run_examples("Example match/#{description}", times, example_meta: { apply_it: true })
+        end
+      end
+
+      implementations.each do |prefix, description|
+        x.report("Group match -- #{description} singleton group support") do |times|
+          prepare_implementation(prefix)
+          define_and_run_examples("Group match/#{description}", times, group_meta: { apply_it: true })
+        end
+      end
+
+      implementations.each do |prefix, description|
+        x.report("Both match -- #{description} singleton group support") do |times|
+          prepare_implementation(prefix)
+          define_and_run_examples("Both match/#{description}", times,
+                                  example_meta: { apply_it: true },
+                                  group_meta: { apply_it: true })
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/benchmarks/singleton_example_groups/with_config_hooks.rb b/rspec-core/benchmarks/singleton_example_groups/with_config_hooks.rb
new file mode 100644
index 0000000..08f4926
--- /dev/null
+++ b/rspec-core/benchmarks/singleton_example_groups/with_config_hooks.rb
@@ -0,0 +1,28 @@
+require_relative "helper"
+
+RSpec.configure do |c|
+  10.times do
+    c.before(:context, :apply_it) { }
+    c.after(:context,  :apply_it) { }
+  end
+end
+
+BenchmarkHelpers.run_benchmarks
+
+__END__
+No match -- without singleton group support
+                        575.250  (±29.0%) i/s -      2.484k
+No match -- with singleton group support
+                        503.671  (±21.8%) i/s -      2.250k
+Example match -- without singleton group support
+                        544.191  (±25.7%) i/s -      2.160k
+Example match -- with singleton group support
+                        413.538  (±22.2%) i/s -      1.715k
+Group match -- without singleton group support
+                        517.998  (±28.2%) i/s -      2.058k
+Group match -- with singleton group support
+                        431.554  (±15.3%) i/s -      1.960k
+Both match -- without singleton group support
+                        525.306  (±25.1%) i/s -      2.107k in   5.556760s
+Both match -- with singleton group support
+                        440.288  (±16.6%) i/s -      1.848k
diff --git a/rspec-core/benchmarks/singleton_example_groups/with_config_hooks_module_inclusions_and_shared_context_inclusions.rb b/rspec-core/benchmarks/singleton_example_groups/with_config_hooks_module_inclusions_and_shared_context_inclusions.rb
new file mode 100644
index 0000000..9eee773
--- /dev/null
+++ b/rspec-core/benchmarks/singleton_example_groups/with_config_hooks_module_inclusions_and_shared_context_inclusions.rb
@@ -0,0 +1,35 @@
+require_relative "helper"
+
+RSpec.configure do |c|
+  10.times do
+    c.before(:context, :apply_it) { }
+    c.after(:context,  :apply_it) { }
+    c.include Module.new, :apply_it
+  end
+end
+
+1.upto(10) do |i|
+  RSpec.shared_context "context #{i}", :apply_it do
+  end
+end
+
+BenchmarkHelpers.run_benchmarks
+
+__END__
+
+No match -- without singleton group support
+                        544.396  (±34.0%) i/s -      2.340k
+No match -- with singleton group support
+                        451.635  (±31.0%) i/s -      1.935k
+Example match -- without singleton group support
+                        538.788  (±23.8%) i/s -      2.450k
+Example match -- with singleton group support
+                        342.990  (±22.4%) i/s -      1.440k
+Group match -- without singleton group support
+                        509.969  (±26.7%) i/s -      2.070k
+Group match -- with singleton group support
+                        405.284  (±20.5%) i/s -      1.518k
+Both match -- without singleton group support
+                        513.344  (±24.0%) i/s -      1.927k
+Both match -- with singleton group support
+                        406.111  (±18.5%) i/s -      1.760k
diff --git a/rspec-core/benchmarks/singleton_example_groups/with_module_inclusions.rb b/rspec-core/benchmarks/singleton_example_groups/with_module_inclusions.rb
new file mode 100644
index 0000000..e3a8c43
--- /dev/null
+++ b/rspec-core/benchmarks/singleton_example_groups/with_module_inclusions.rb
@@ -0,0 +1,28 @@
+require_relative "helper"
+
+RSpec.configure do |c|
+  1.upto(10) do
+    c.include Module.new, :apply_it
+  end
+end
+
+BenchmarkHelpers.run_benchmarks
+
+__END__
+
+No match -- without singleton group support
+                        555.498  (±27.0%) i/s -      2.496k
+No match -- with singleton group support
+                        529.826  (±23.0%) i/s -      2.397k in   5.402305s
+Example match -- without singleton group support
+                        541.845  (±29.0%) i/s -      2.208k
+Example match -- with singleton group support
+                        465.440  (±20.4%) i/s -      2.091k
+Group match -- without singleton group support
+                        530.976  (±24.1%) i/s -      2.303k
+Group match -- with singleton group support
+                        505.291  (±18.8%) i/s -      2.226k
+Both match -- without singleton group support
+                        542.168  (±28.4%) i/s -      2.067k in   5.414905s
+Both match -- with singleton group support
+                        503.226  (±27.2%) i/s -      1.880k in   5.621210s
diff --git a/rspec-core/benchmarks/singleton_example_groups/with_no_config_hooks_or_inclusions.rb b/rspec-core/benchmarks/singleton_example_groups/with_no_config_hooks_or_inclusions.rb
new file mode 100644
index 0000000..ec7849d
--- /dev/null
+++ b/rspec-core/benchmarks/singleton_example_groups/with_no_config_hooks_or_inclusions.rb
@@ -0,0 +1,22 @@
+require_relative "helper"
+
+BenchmarkHelpers.run_benchmarks
+
+__END__
+
+No match -- without singleton group support
+                        565.198  (±28.8%) i/s -      2.438k
+No match -- with singleton group support
+                        539.781  (±18.9%) i/s -      2.496k
+Example match -- without singleton group support
+                        539.287  (±28.2%) i/s -      2.450k in   5.555471s
+Example match -- with singleton group support
+                        511.576  (±28.1%) i/s -      2.058k
+Group match -- without singleton group support
+                        535.298  (±23.2%) i/s -      2.352k
+Group match -- with singleton group support
+                        539.454  (±19.1%) i/s -      2.350k
+Both match -- without singleton group support
+                        550.932  (±32.1%) i/s -      2.145k in   5.930432s
+Both match -- with singleton group support
+                        540.183  (±19.6%) i/s -      2.300k
diff --git a/rspec-core/benchmarks/singleton_example_groups/with_shared_context_inclusions.rb b/rspec-core/benchmarks/singleton_example_groups/with_shared_context_inclusions.rb
new file mode 100644
index 0000000..2d99ec6
--- /dev/null
+++ b/rspec-core/benchmarks/singleton_example_groups/with_shared_context_inclusions.rb
@@ -0,0 +1,28 @@
+require_relative "helper"
+
+1.upto(10) do |i|
+  RSpec.shared_context "context #{i}", :apply_it do
+  end
+end
+
+BenchmarkHelpers.run_benchmarks
+# BenchmarkHelpers.profile(1000)
+
+__END__
+
+No match -- without singleton group support
+                        563.304  (±29.6%) i/s -      2.385k
+No match -- with singleton group support
+                        538.738  (±22.3%) i/s -      2.209k
+Example match -- without singleton group support
+                        546.605  (±25.6%) i/s -      2.450k
+Example match -- with singleton group support
+                        421.111  (±23.5%) i/s -      1.845k
+Group match -- without singleton group support
+                        536.267  (±27.4%) i/s -      2.050k
+Group match -- with singleton group support
+                        508.644  (±17.7%) i/s -      2.268k
+Both match -- without singleton group support
+                        538.047  (±27.7%) i/s -      2.067k in   5.431649s
+Both match -- with singleton group support
+                        505.388  (±26.7%) i/s -      1.880k in   5.578614s
diff --git a/rspec-core/benchmarks/sort_by_v_shuffle.rb b/rspec-core/benchmarks/sort_by_v_shuffle.rb
new file mode 100644
index 0000000..1223c90
--- /dev/null
+++ b/rspec-core/benchmarks/sort_by_v_shuffle.rb
@@ -0,0 +1,83 @@
+require "benchmark"
+
+# This benchmark demonstrates the speed of Array#shuffle versus sorting by
+# random numbers. This is in reference to ordering examples using the
+# --order=rand command line flag. Array#shuffle also respects seeded random via
+# Kernel.srand.
+
+LIST = (1..1_000).to_a.freeze
+
+Benchmark.bmbm do |x|
+  x.report("sort_by") do
+    1_000.times do
+      LIST.sort_by { Kernel.rand(LIST.size) }
+    end
+  end
+
+  x.report("shuffle") do
+    1_000.times do
+      LIST.shuffle
+    end
+  end
+
+  # http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+  #
+  # We use this algorithm as an alternative to `shuffle` on
+  # rubies (< 1.9.3) for which Array#shuffle does not accept
+  # a `:random` option. We do this to avoid affecting ruby's
+  # global randomization.
+  x.report('fisher-yates') do
+    1_000.times do
+      rng = Random.new
+      list = LIST.dup
+      LIST.size.times do |i|
+        j = i + rng.rand(LIST.size - i)
+        next if i == j
+        list[i], list[j] = list[j], list[i]
+      end
+    end
+  end
+end
+
+=begin
+
+Ruby 2.0.0:
+
+Rehearsal ------------------------------------------------
+sort_by        0.570000   0.010000   0.580000 (  0.581875)
+shuffle        0.020000   0.000000   0.020000 (  0.021524)
+fisher-yates   0.370000   0.020000   0.390000 (  0.387855)
+--------------------------------------- total: 0.990000sec
+
+                   user     system      total        real
+sort_by        0.560000   0.000000   0.560000 (  0.561014)
+shuffle        0.010000   0.000000   0.010000 (  0.019814)
+fisher-yates   0.350000   0.010000   0.360000 (  0.358932)
+
+Ruby 1.9.3:
+
+Rehearsal ------------------------------------------------
+sort_by        0.690000   0.010000   0.700000 (  0.701035)
+shuffle        0.020000   0.000000   0.020000 (  0.017603)
+fisher-yates   0.440000   0.020000   0.460000 (  0.464778)
+--------------------------------------- total: 1.180000sec
+
+                   user     system      total        real
+sort_by        0.690000   0.000000   0.690000 (  0.697824)
+shuffle        0.020000   0.000000   0.020000 (  0.018622)
+fisher-yates   0.440000   0.010000   0.450000 (  0.452260)
+
+JRuby:
+
+Rehearsal ------------------------------------------------
+sort_by        2.550000   0.050000   2.600000 (  1.325000)
+shuffle        0.090000   0.000000   0.090000 (  0.057000)
+fisher-yates   0.770000   0.010000   0.780000 (  0.477000)
+--------------------------------------- total: 3.470000sec
+
+                   user     system      total        real
+sort_by        0.470000   0.010000   0.480000 (  0.442000)
+shuffle        0.040000   0.000000   0.040000 (  0.042000)
+fisher-yates   0.300000   0.010000   0.310000 (  0.283000)
+
+=end
diff --git a/rspec-core/benchmarks/to_proc_v_not_to_proc.rb b/rspec-core/benchmarks/to_proc_v_not_to_proc.rb
new file mode 100644
index 0000000..e1e5c4c
--- /dev/null
+++ b/rspec-core/benchmarks/to_proc_v_not_to_proc.rb
@@ -0,0 +1,539 @@
+require 'benchmark'
+
+$n = 5000
+
+puts
+
+def report(header)
+  reals = []
+  Benchmark.benchmark do |bm|
+    3.times do
+      reals << bm.report { $n.times { yield } }.real
+    end
+  end
+
+  [header, reals.inject(&:+) / reals.count]
+end
+
+avgs = []
+
+def a(&block)
+  b(&block)
+end
+
+def b(&block)
+  block.call
+end
+
+def c(&block)
+  d(block)
+end
+
+def d(block)
+  block.call
+end
+
+puts "#{$n} invocations"
+puts
+
+avgs << report("with &") {
+  a { 100*100*100}
+}
+
+puts
+
+avgs << report("without &") {
+  c { 100*100*100}
+}
+
+puts
+
+puts avgs
+
+puts
+
+__END__
+
+ ruby -e "10.times { system 'ruby benchmarks/to_proc_v_not_to_proc.rb' }"
+
+1000 invocations
+
+   0.010000   0.000000   0.010000 (  0.000958)
+   0.000000   0.000000   0.000000 (  0.000917)
+   0.000000   0.000000   0.000000 (  0.000893)
+
+   0.000000   0.000000   0.000000 (  0.001660)
+   0.000000   0.000000   0.000000 (  0.002686)
+   0.000000   0.000000   0.000000 (  0.000686)
+
+with &
+0.0009226666666666667
+without &
+0.0016773333333333334
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000898)
+   0.000000   0.000000   0.000000 (  0.000868)
+   0.010000   0.000000   0.010000 (  0.000768)
+
+   0.000000   0.000000   0.000000 (  0.001615)
+   0.000000   0.000000   0.000000 (  0.002917)
+   0.000000   0.000000   0.000000 (  0.000996)
+
+with &
+0.0008446666666666666
+without &
+0.0018426666666666667
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000884)
+   0.000000   0.000000   0.000000 (  0.001217)
+   0.000000   0.000000   0.000000 (  0.000877)
+
+   0.000000   0.000000   0.000000 (  0.001617)
+   0.010000   0.000000   0.010000 (  0.002718)
+   0.000000   0.000000   0.000000 (  0.000772)
+
+with &
+0.0009926666666666667
+without &
+0.0017023333333333335
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000868)
+   0.000000   0.000000   0.000000 (  0.000874)
+   0.000000   0.000000   0.000000 (  0.000829)
+
+   0.000000   0.000000   0.000000 (  0.001394)
+   0.010000   0.000000   0.010000 (  0.002330)
+   0.000000   0.000000   0.000000 (  0.000712)
+
+with &
+0.000857
+without &
+0.0014786666666666665
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000901)
+   0.000000   0.000000   0.000000 (  0.000876)
+   0.010000   0.000000   0.010000 (  0.000851)
+
+   0.000000   0.000000   0.000000 (  0.001465)
+   0.000000   0.000000   0.000000 (  0.002478)
+   0.000000   0.000000   0.000000 (  0.000661)
+
+with &
+0.000876
+without &
+0.0015346666666666668
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000907)
+   0.000000   0.000000   0.000000 (  0.000810)
+   0.000000   0.000000   0.000000 (  0.000796)
+
+   0.000000   0.000000   0.000000 (  0.001407)
+   0.010000   0.000000   0.010000 (  0.002549)
+   0.000000   0.000000   0.000000 (  0.000652)
+
+with &
+0.0008376666666666667
+without &
+0.001536
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000852)
+   0.000000   0.000000   0.000000 (  0.000884)
+   0.000000   0.000000   0.000000 (  0.000829)
+
+   0.010000   0.000000   0.010000 (  0.001471)
+   0.000000   0.000000   0.000000 (  0.002701)
+   0.000000   0.000000   0.000000 (  0.000729)
+
+with &
+0.000855
+without &
+0.001633666666666667
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.001089)
+   0.010000   0.000000   0.010000 (  0.000957)
+   0.000000   0.000000   0.000000 (  0.000813)
+
+   0.000000   0.000000   0.000000 (  0.001477)
+   0.000000   0.000000   0.000000 (  0.002500)
+   0.000000   0.000000   0.000000 (  0.000666)
+
+with &
+0.000953
+without &
+0.0015476666666666666
+
+
+1000 invocations
+
+   0.010000   0.000000   0.010000 (  0.000839)
+   0.000000   0.000000   0.000000 (  0.000846)
+   0.000000   0.000000   0.000000 (  0.000812)
+
+   0.000000   0.000000   0.000000 (  0.001497)
+   0.000000   0.000000   0.000000 (  0.002415)
+   0.000000   0.000000   0.000000 (  0.000729)
+
+with &
+0.0008323333333333334
+without &
+0.0015470000000000004
+
+
+1000 invocations
+
+   0.000000   0.000000   0.000000 (  0.000904)
+   0.000000   0.000000   0.000000 (  0.000928)
+   0.000000   0.000000   0.000000 (  0.000904)
+
+   0.010000   0.000000   0.010000 (  0.001649)
+   0.000000   0.000000   0.000000 (  0.002838)
+   0.000000   0.000000   0.000000 (  0.000799)
+
+with &
+0.0009119999999999999
+without &
+0.001762
+
+$ ruby -e "10.times { system 'ruby benchmarks/to_proc_v_not_to_proc.rb' }"
+
+5000 invocations
+
+   0.000000   0.000000   0.000000 (  0.007017)
+   0.010000   0.000000   0.010000 (  0.005138)
+   0.000000   0.000000   0.000000 (  0.005207)
+
+   0.010000   0.000000   0.010000 (  0.005075)
+   0.000000   0.000000   0.000000 (  0.005230)
+   0.010000   0.000000   0.010000 (  0.006287)
+
+with &
+0.005787333333333333
+without &
+0.005530666666666666
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006685)
+   0.010000   0.000000   0.010000 (  0.006263)
+   0.000000   0.000000   0.000000 (  0.005923)
+
+   0.010000   0.000000   0.010000 (  0.005996)
+   0.000000   0.000000   0.000000 (  0.005626)
+   0.010000   0.000000   0.010000 (  0.006743)
+
+with &
+0.006290333333333334
+without &
+0.006121666666666667
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.007708)
+   0.010000   0.000000   0.010000 (  0.005533)
+   0.000000   0.000000   0.000000 (  0.005451)
+
+   0.010000   0.000000   0.010000 (  0.005297)
+   0.000000   0.000000   0.000000 (  0.005129)
+   0.010000   0.000000   0.010000 (  0.006554)
+
+with &
+0.0062306666666666665
+without &
+0.005659999999999999
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006615)
+   0.000000   0.000000   0.000000 (  0.006449)
+   0.010000   0.000000   0.010000 (  0.005974)
+
+   0.010000   0.000000   0.010000 (  0.005291)
+   0.000000   0.000000   0.000000 (  0.005502)
+   0.010000   0.000000   0.010000 (  0.007272)
+
+with &
+0.006346
+without &
+0.006021666666666667
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006719)
+   0.000000   0.000000   0.000000 (  0.005280)
+   0.010000   0.000000   0.010000 (  0.005472)
+
+   0.000000   0.000000   0.000000 (  0.005319)
+   0.010000   0.000000   0.010000 (  0.005174)
+   0.010000   0.000000   0.010000 (  0.006049)
+
+with &
+0.005823666666666667
+without &
+0.005513999999999999
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006857)
+   0.010000   0.000000   0.010000 (  0.009484)
+   0.000000   0.000000   0.000000 (  0.007458)
+
+   0.010000   0.000000   0.010000 (  0.006191)
+   0.010000   0.000000   0.010000 (  0.005341)
+   0.000000   0.000000   0.000000 (  0.005976)
+
+with &
+0.007933
+without &
+0.005836000000000001
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.007637)
+   0.000000   0.000000   0.000000 (  0.005701)
+   0.010000   0.000000   0.010000 (  0.005383)
+
+   0.000000   0.000000   0.000000 (  0.005185)
+   0.010000   0.000000   0.010000 (  0.005211)
+   0.010000   0.000000   0.010000 (  0.008762)
+
+with &
+0.006240333333333333
+without &
+0.006386
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006861)
+   0.010000   0.000000   0.010000 (  0.010632)
+   0.000000   0.000000   0.000000 (  0.006004)
+
+   0.010000   0.000000   0.010000 (  0.005384)
+   0.010000   0.000000   0.010000 (  0.006040)
+   0.000000   0.000000   0.000000 (  0.008638)
+
+with &
+0.007832333333333334
+without &
+0.006687333333333333
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006673)
+   0.000000   0.000000   0.000000 (  0.005332)
+   0.010000   0.000000   0.010000 (  0.005348)
+
+   0.000000   0.000000   0.000000 (  0.005212)
+   0.010000   0.000000   0.010000 (  0.005176)
+   0.010000   0.000000   0.010000 (  0.005989)
+
+with &
+0.005784333333333333
+without &
+0.0054589999999999994
+
+
+5000 invocations
+
+   0.010000   0.000000   0.010000 (  0.006795)
+   0.000000   0.000000   0.000000 (  0.005278)
+   0.010000   0.000000   0.010000 (  0.005466)
+
+   0.010000   0.000000   0.010000 (  0.006348)
+   0.000000   0.000000   0.000000 (  0.007129)
+   0.010000   0.000000   0.010000 (  0.009930)
+
+with &
+0.005846333333333333
+without &
+0.007802333333333332
+
+
+$ ruby -e "10.times { system 'ruby benchmarks/to_proc_v_not_to_proc.rb' }"
+
+10000 invocations
+
+   0.010000   0.000000   0.010000 (  0.012112)
+   0.010000   0.000000   0.010000 (  0.010734)
+   0.020000   0.000000   0.020000 (  0.013636)
+
+   0.010000   0.000000   0.010000 (  0.014597)
+   0.010000   0.000000   0.010000 (  0.011408)
+   0.020000   0.000000   0.020000 (  0.011720)
+
+with &
+0.012160666666666667
+without &
+0.012575000000000001
+
+
+10000 invocations
+
+   0.020000   0.000000   0.020000 (  0.012789)
+   0.010000   0.000000   0.010000 (  0.010452)
+   0.010000   0.000000   0.010000 (  0.012485)
+
+   0.010000   0.000000   0.010000 (  0.011538)
+   0.010000   0.000000   0.010000 (  0.010159)
+   0.010000   0.000000   0.010000 (  0.011292)
+
+with &
+0.011908666666666665
+without &
+0.010996333333333335
+
+
+10000 invocations
+
+   0.020000   0.000000   0.020000 (  0.015100)
+   0.010000   0.000000   0.010000 (  0.011080)
+   0.010000   0.000000   0.010000 (  0.016177)
+
+   0.020000   0.000000   0.020000 (  0.013541)
+   0.010000   0.000000   0.010000 (  0.010604)
+   0.010000   0.000000   0.010000 (  0.011566)
+
+with &
+0.014119000000000001
+without &
+0.011903666666666667
+
+
+10000 invocations
+
+   0.010000   0.000000   0.010000 (  0.013065)
+   0.020000   0.000000   0.020000 (  0.011556)
+   0.010000   0.000000   0.010000 (  0.012144)
+
+   0.010000   0.000000   0.010000 (  0.009862)
+   0.010000   0.000000   0.010000 (  0.011292)
+   0.010000   0.000000   0.010000 (  0.014442)
+
+with &
+0.012255
+without &
+0.011865333333333334
+
+
+10000 invocations
+
+   0.010000   0.000000   0.010000 (  0.015715)
+   0.010000   0.000000   0.010000 (  0.011772)
+   0.020000   0.000000   0.020000 (  0.014638)
+
+   0.010000   0.000000   0.010000 (  0.015350)
+   0.010000   0.000000   0.010000 (  0.011328)
+   0.020000   0.000000   0.020000 (  0.013594)
+
+with &
+0.014041666666666666
+without &
+0.013424
+
+
+10000 invocations
+
+   0.010000   0.000000   0.010000 (  0.013395)
+   0.020000   0.000000   0.020000 (  0.012911)
+   0.010000   0.000000   0.010000 (  0.012247)
+
+   0.010000   0.000000   0.010000 (  0.011711)
+   0.010000   0.000000   0.010000 (  0.013390)
+   0.020000   0.000000   0.020000 (  0.013257)
+
+with &
+0.012851000000000001
+without &
+0.012785999999999999
+
+
+10000 invocations
+
+   0.020000   0.000000   0.020000 (  0.014683)
+   0.010000   0.000000   0.010000 (  0.012940)
+   0.010000   0.000000   0.010000 (  0.012317)
+
+   0.020000   0.000000   0.020000 (  0.015153)
+   0.010000   0.000000   0.010000 (  0.014927)
+   0.020000   0.000000   0.020000 (  0.015575)
+
+with &
+0.013313333333333335
+without &
+0.015218333333333334
+
+
+10000 invocations
+
+   0.020000   0.000000   0.020000 (  0.016568)
+   0.010000   0.000000   0.010000 (  0.014674)
+   0.020000   0.000000   0.020000 (  0.013102)
+
+   0.010000   0.000000   0.010000 (  0.010525)
+   0.010000   0.000000   0.010000 (  0.012797)
+   0.010000   0.000000   0.010000 (  0.013213)
+
+with &
+0.014781333333333334
+without &
+0.012178333333333333
+
+
+10000 invocations
+
+   0.010000   0.000000   0.010000 (  0.015328)
+   0.020000   0.000000   0.020000 (  0.017426)
+   0.020000   0.000000   0.020000 (  0.020689)
+
+   0.010000   0.000000   0.010000 (  0.014016)
+   0.010000   0.000000   0.010000 (  0.011353)
+   0.020000   0.000000   0.020000 (  0.017668)
+
+with &
+0.01781433333333333
+without &
+0.014345666666666668
+
+
+10000 invocations
+
+   0.020000   0.000000   0.020000 (  0.015356)
+   0.010000   0.000000   0.010000 (  0.015558)
+   0.020000   0.000000   0.020000 (  0.012719)
+
+   0.010000   0.000000   0.010000 (  0.011133)
+   0.010000   0.000000   0.010000 (  0.010461)
+   0.010000   0.000000   0.010000 (  0.013035)
+
+with &
+0.014544333333333333
+without &
+0.011543
diff --git a/rspec-core/cucumber.yml b/rspec-core/cucumber.yml
new file mode 100644
index 0000000..e37a8bc
--- /dev/null
+++ b/rspec-core/cucumber.yml
@@ -0,0 +1,6 @@
+<%
+exclusions = []
+exclusions << ' --tags ~@no-jruby' if RUBY_PLATFORM == 'java'
+%>
+default: --require features --strict --format progress --tags ~@wip<%= exclusions.join %> features
+wip:     --require features --tags @wip:30 --wip features
diff --git a/rspec-core/exe/rspec b/rspec-core/exe/rspec
new file mode 100755
index 0000000..7ee5fd8
--- /dev/null
+++ b/rspec-core/exe/rspec
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+
+require 'rspec/core'
+RSpec::Core::Runner.invoke
diff --git a/rspec-core/features/.nav b/rspec-core/features/.nav
new file mode 100644
index 0000000..415b7d0
--- /dev/null
+++ b/rspec-core/features/.nav
@@ -0,0 +1,62 @@
+- Upgrade.md
+- Changelog.md
+- Autotest.md
+- example_groups:
+  - basic_structure.feature
+  - shared_examples.feature
+  - shared_context.feature
+- command_line:
+  - configure.feature
+  - example_name_option.feature
+  - format_option.feature
+  - tag.feature
+  - line_number_appended_to_path.feature
+  - exit_status.feature
+  - order.md (`--order` option)
+  - rake_task.feature
+- pending:
+  - pending_examples.feature
+- hooks:
+  - before_and_after_hooks.feature
+  - around_hooks.feature
+  - filtering.feature
+- subject:
+  - implicit_subject.feature
+  - explicit_subject.feature
+  - attribute_of_subject.feature
+  - implicit_receiver.feature
+- helper_methods:
+  - let.feature
+  - arbitrary_methods.feature
+  - modules.feature
+- metadata:
+  - current_example.feature
+  - described_class.feature
+  - user_defined.feature
+- filtering:
+  - inclusion_filters.feature
+  - exclusion_filters.feature
+  - if_and_unless.feature
+  - run_all_when_everything_filtered.feature
+- configuration:
+  - read_options_from_file.feature
+  - fail_fast.feature
+  - custom_settings.feature
+  - alias_example_to.feature
+  - default_path.feature
+- expectation_framework_integration:
+  - configure_expectation_framework.feature
+- mock_framework_integration:
+  - use_rspec.feature
+  - use_flexmock.feature
+  - use_mocha.feature
+  - use_rr.feature
+  - use_any_framework.feature
+- formatters:
+  - text_formatter.feature
+  - configurable_colors.feature
+  - json_formatter.feature
+  - custom_formatter.feature
+- spec_files:
+  - arbitrary_file_suffix.feature
+- core_standalone.feature
diff --git a/rspec-core/features/README.md b/rspec-core/features/README.md
new file mode 100644
index 0000000..a188108
--- /dev/null
+++ b/rspec-core/features/README.md
@@ -0,0 +1,13 @@
+rspec-core provides the structure for RSpec code examples:
+
+    describe Account do
+      it "has a balance of zero when first opened" do
+        # example code goes here - for more on the
+        # code inside the examples, see rspec-expectations
+        # and rspec-mocks
+      end
+    end
+
+## Issues
+
+This documentation is [open source](https://github.com/rspec/rspec-core/tree/master/features), and a work in progress.  If you find it incomplete or confusing, please [submit an issue](http://github.com/rspec/rspec-core/issues), or, better yet, [a pull request](http://github.com/rspec/rspec-core).
diff --git a/rspec-core/features/Upgrade.md b/rspec-core/features/Upgrade.md
new file mode 100644
index 0000000..c57e84b
--- /dev/null
+++ b/rspec-core/features/Upgrade.md
@@ -0,0 +1,352 @@
+The [Changelog](changelog) has a complete list of everything that changed, but
+here are more detailed explanations for those items that warrant them.
+
+# rspec-core-2.7.0.rc1
+
+## what's new
+
+### `rspec` command with no arguments
+
+Now you can just type
+
+    rspec
+
+to run all the specs in the `spec` directory.  If you keep your specs in a
+different directory, you can override the default with the `--default-path`
+argument in a config file:
+
+    # in .rspec
+    --default-path specs
+
+### `rspec` command supports multiple line numbers
+
+Use either of the following to run the examples declared on lines
+37 and 42 of `a_spec.rb`:
+
+    rspec path/to/a_spec.rb --line_number 37 --line_number 42
+    rspec path/to/a_spec.rb:37:42
+
+## what's changed
+
+### `skip_bundler` and `gemfile` rake task options are deprecated and have no effect.
+
+RSpec's rake task invokes the `rspec` command in a subshell. If you invoke
+`bundle exec rake` or include `Bundler.setup` in your `Rakefile`, then
+Bundler will be activated in the subshell as well.
+
+Previously, the rake task managed this for you based on the presence of a
+`Gemfile`. In 2.7.0.rc1, this is done based on the presence of the
+`BUNDLE_GEMFILE` environment variable, which is set in the parent shell by Bundler.
+
+In 2.7.0.rc2 (not yet released), the rake task doesn't do anything at all.
+Turns out Bundler just does the right thing, so rspec doesn't need to do
+anything.
+
+# rspec-core-2.6
+
+## new APIs for sharing content
+
+Use `shared_context` together with `include_context` to share before/after
+hooks, let declarations, and method definitions across example groups.
+
+Use `shared_examples` together with `include_examples` to share examples
+across different contexts.
+
+All of the old APIs are still supported, but these 4 are easy to remember, and
+serve most use cases.
+
+See `shared_context` and `shared_examples` under "Example Groups" for more
+information.
+
+## `treat_symbols_as_metadata_keys_with_true_values`
+
+Yes it's a long name, but it's a great feature, and it's going to be the
+default behavior in rspec-3. This lets you add metadata to a group or example
+like this:
+
+    describe "something", :awesome do
+      ...
+
+And then you can run that group (or example) using the tags feature:
+
+    rspec spec --tag awesome
+
+We're making this an opt-in for rspec-2.6 because `describe "string", :symbol`
+is a perfectly legal construct in pre-2.6 releases and we want to maintain
+compatibility in minor releases as much as is possible.
+
+# rspec-core-2.3
+
+## `config.expect_with`
+
+Use this to configure RSpec to use rspec/expectations (default),
+stdlib assertions (Test::Unit with Ruby 1.8, MiniTest with Ruby 1.9),
+or both:
+
+    RSpec.configure do |config|
+      config.expect_with :rspec          # => rspec/expectations
+      config.expect_with :stdlib         # => Test::Unit or MinitTest
+      config.expect_with :rspec, :stdlib # => both
+    end
+
+# rspec-core-2.1
+
+## Command line
+
+### `--tags`
+
+Now you can tag groups and examples using metadata and access those tags from
+the command line. So if you have a group with `:foo => true`:
+
+    describe "something", :foo => true do
+      it "does something" do
+        # ...
+      end
+    end
+
+... now you can run just that group like this:
+
+    rspec spec --tags foo
+
+### `--fail-fast`
+
+Add this flag to the command line to tell rspec to clean up and exit after the
+first failure:
+
+    rspec spec --fail-fast
+
+## Metata/filtering
+
+### :if and :unless keys
+
+Use :if and :unless keys to conditionally run examples with simple boolean
+expressions:
+
+    describe "something" do
+      it "does something", :if => RUBY_VERSION == 1.8.7 do
+        # ...
+      end
+      it "does something", :unless => RUBY_VERSION == 1.8.7 do
+        # ...
+      end
+    end
+
+## Conditionally 'pending' examples
+
+Make examples pending based on a condition.  This is most useful when you
+have an example that runs in multiple contexts and fails in one of those due to
+a bug in a third-party dependency that you expect to be fixed in the future.
+
+    describe "something" do
+      it "does something that doesn't yet work right on JRuby" do
+        pending("waiting for the JRuby team to fix issue XYZ", :if => RUBY_PLATFORM == 'java') do
+          # the content of your spec
+        end
+      end
+    end
+
+This example would run normally on all ruby interpretters except JRuby.  On JRuby,
+it uses the block form of `pending`, which causes the example to still be run and
+will remain pending as long as it fails.  In the future, if you upgraded your
+JRuby installation to a newer release that allows the example to pass, RSpec
+will report it as a failure (`Expected pending '...' to fail.  No Error was raised.`),
+so that know that you can remove the call to `pending`.
+
+# New features in rspec-core-2.0
+
+### Runner
+
+The new runner for rspec-2 comes from Micronaut.
+
+### Metadata!
+
+In rspec-2, every example and example group comes with metadata information
+like the file and line number on which it was declared, the arguments passed to
+`describe` and `it`, etc.  This metadata can be appended to through a hash
+argument passed to `describe` or `it`, allowing us to pre and post-process
+each example in a variety of ways.
+
+### Filtering
+
+The most obvious use is for filtering the run. For example:
+
+    # in spec/spec_helper.rb
+    RSpec.configure do |c|
+      c.filter_run :focus => true
+    end
+
+    # in any spec file
+    describe "something" do
+      it "does something", :focus => true do
+        # ....
+      end
+    end
+
+When you run the `rspec` command, rspec will run only the examples that have
+`:focus => true` in the hash.
+
+You can also add `run_all_when_everything_filtered` to the config:
+
+    RSpec.configure do |c|
+      c.filter_run :focus => true
+      c.run_all_when_everything_filtered = true
+    end
+
+Now if there are no examples tagged with `:focus => true`, all examples
+will be run. This makes it really easy to focus on one example for a
+while, but then go back to running all of the examples by removing that
+argument from `it`. Works with `describe` too, in which case it runs
+all of the examples in that group.
+
+The configuration will accept a lambda, which provides a lot of flexibility
+in filtering examples. Say, for example, you have a spec for functionality that
+behaves slightly differently in Ruby 1.8 and Ruby 1.9. We have that in
+rspec-core, and here's how we're getting the right stuff to run under the
+right version:
+
+    # in spec/spec_helper.rb
+    RSpec.configure do |c|
+      c.exclusion_filter = { :ruby => lambda {|version|
+        !(RUBY_VERSION.to_s =~ /^#{version.to_s}/)
+      }}
+    end
+
+    # in any spec file
+    describe "something" do
+      it "does something", :ruby => 1.8 do
+        # ....
+      end
+
+      it "does something", :ruby => 1.9 do
+        # ....
+      end
+    end
+
+In this case, we're using `exclusion_filter` instead of `filter_run` or
+`filter`, which indicate _inclusion_ filters. So each of those examples is
+excluded if we're _not_ running the version of Ruby they work with.
+
+### Shared example groups
+
+Shared example groups are now run in a nested group within the including group
+(they used to be run in the same group). Nested groups inherit `before`, `after`,
+`around`, and `let` hooks, as well as any methods that are defined in the parent
+group.
+
+This new approach provides better encapsulation, better output, and an
+opportunity to add contextual information to the shared group via a block
+passed to `it_should_behave_like`.
+
+See [features/example\_groups/shared\_example\_group.feature](http://github.com/rspec/rspec-core/blob/master/features/example_groups/shared_example_group.feature) for more information.
+
+**NOTICE:** An example group including shared examples no longer has access to
+any of the methods, hooks or state defined inside the shared group. This will
+break rspec-1 specs that were using shared example groups to extend the behavior
+of including groups.
+
+# Upgrading from rspec-1.x
+
+### rspec command
+
+The command to run specs is now `rspec` instead of `spec`.
+
+    rspec ./spec
+
+#### Co-habitation of rspec-1 and rspec-2
+
+Early beta versions of RSpec-2 included a `spec` command, which conflicted with
+the RSpec-1 `spec` command because RSpec-1's was installed by the rspec gem,
+while RSpec-2's is installed by the rspec-core gem.
+
+If you installed one of these early versions, the safest bet is to uninstall
+rspec-1 and rspec-core-2, and then reinstall both. After you do this, you will
+be able to run rspec-2 like this:
+
+    rspec ./spec
+
+... and rspec-1 like this:
+
+    spec _1.3.1_ ./spec
+
+Rubygems inspects the first argument to any gem executable to see if it's
+formatted like a version number surrounded by underscores. If so, it uses that
+version (e.g.  `1.3.1`). If not, it uses the most recent version (e.g.
+`2.0.0`).
+
+### rake task
+
+A few things changed in the Rake task used to run specs:
+
+1.  The file in which it is defined changed from `spec/rake/spectask` to
+    `rspec/core/rake_task`
+
+2.  The `spec_opts` accessor has been deprecated in favor of `rspec_opts`. Also,
+    the `rspec` command no longer supports the `--options` command line option
+    so the options must be embedded directly in the Rakefile, or stored in the
+    `.rspec` files mentioned above.
+
+3.  The `spec_files` accessor has been replaced by `pattern`.
+
+        # rspec-1
+        require 'spec/rake/spectask'
+
+        Spec::Rake::SpecTask.new do |t|
+          t.spec_opts = ['--options', "\"spec/spec.opts\""]
+          t.spec_files = FileList['spec/**/*.rb']
+        end
+
+        # rspec-2
+        require 'rspec/core/rake_task'
+
+        RSpec::Core::RakeTask.new do |t|
+          t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
+          t.pattern = 'spec/**/*_spec.rb'
+        end
+
+### RSpec is the new Spec
+
+The root namespace (top level module) is now `RSpec` instead of `Spec`, and
+the root directory under `lib` within all of the `rspec` gems is `rspec` instead of `spec`.
+
+### Configuration
+
+Typically in `spec/spec_helper.rb`, configuration is now done like this:
+
+    RSpec.configure do |c|
+      # ....
+    end
+
+### .rspec
+
+Command line options can be persisted in a `.rspec` file in a project. You
+can also store a `.rspec` file in your home directory (`~/.rspec`) with global
+options. Precedence is:
+
+    command line
+    ./.rspec
+    ~/.rspec
+
+### `context` is no longer a top-level method
+
+We removed `context` from the main object because it was creating conflicts with
+IRB and some users who had `Context` domain objects. `describe` is still there,
+so if you want to use `context` at the top level, just alias it:
+
+    alias :context :describe
+
+Of course, you can still use `context` to declare a nested group:
+
+    describe "something" do
+      context "in some context" do
+        it "does something" do
+          # ...
+        end
+      end
+    end
+
+### `$KCODE` no longer set implicitly to `'u'`
+
+In RSpec-1, the runner set `$KCODE` to `'u'`, which impacts, among other
+things, the behaviour of Regular Expressions when applied to non-ascii
+characters. This is no longer the case in RSpec-2.
+
diff --git a/rspec-core/features/clear_examples.feature b/rspec-core/features/clear_examples.feature
new file mode 100644
index 0000000..1398790
--- /dev/null
+++ b/rspec-core/features/clear_examples.feature
@@ -0,0 +1,107 @@
+Feature: Running specs multiple times with different runner options in the same process
+
+  Use `clear_examples` command to clear all example groups between different
+  runs in the same process. It:
+
+  - clears all example groups
+  - restores inclusion and exclusion filters set by configuration
+  - clears inclusion and exclusion filters set by previous spec run (via runner)
+  - resets all time counters (start time, load time, duration, etc.)
+  - resets different counts of examples (all examples, pending and failed)
+
+  ```ruby
+  require "spec_helper"
+
+  RSpec::Core::Runner.run([... some parameters ...])
+
+  RSpec.clear_examples
+
+  RSpec::Core::Runner.run([... different parameters ...])
+  ```
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.filter_run_including :focus => true
+        config.filter_run_excluding :slow => true
+        config.run_all_when_everything_filtered = true
+      end
+      """
+    Given a file named "spec/truth_spec.rb" with:
+    """ruby
+    require 'spec_helper'
+
+    RSpec.describe "truth" do
+      describe true do
+        it "is truthy" do
+          expect(true).to be_truthy
+        end
+
+        it "is not falsy" do
+          expect(true).not_to be_falsy
+        end
+      end
+
+      describe false do
+        it "is falsy" do
+          expect(false).to be_falsy
+        end
+
+        it "is truthy" do
+          expect(false).not_to be_truthy
+        end
+      end
+    end
+    """
+
+  Scenario: Running specs multiple times in the same process
+    Given a file named "scripts/multiple_runs.rb" with:
+      """ruby
+      require 'rspec/core'
+
+      RSpec::Core::Runner.run(['spec'])
+      RSpec.clear_examples
+      RSpec::Core::Runner.run(['spec'])
+      """
+    When I run `ruby scripts/multiple_runs.rb`
+    Then the output should match:
+      """
+      4 examples, 0 failures
+      .*
+      4 examples, 0 failures
+      """
+
+  Scenario: Running specs multiple times in the same process with different parameters
+    Given a file named "spec/bar_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+
+      RSpec.describe 'bar' do
+        subject(:bar) { :focused }
+
+        it 'is focused', :focus do
+          expect(bar).to be(:focused)
+        end
+      end
+      """
+    Given a file named "scripts/different_parameters.rb" with:
+      """ruby
+      require 'rspec/core'
+
+      RSpec::Core::Runner.run(['spec'])
+      RSpec.clear_examples
+      RSpec::Core::Runner.run(['spec/truth_spec.rb:4'])
+      RSpec.clear_examples
+      RSpec::Core::Runner.run(['spec', '-e', 'fals'])
+      """
+    When I run `ruby scripts/different_parameters.rb`
+    Then the output should match:
+      """
+      1 example, 0 failures
+      .*
+      2 examples, 0 failures
+      .*
+      3 examples, 0 failures
+      """
+
diff --git a/rspec-core/features/command_line/README.md b/rspec-core/features/command_line/README.md
new file mode 100644
index 0000000..df3b998
--- /dev/null
+++ b/rspec-core/features/command_line/README.md
@@ -0,0 +1,28 @@
+The `rspec` command comes with several options you can use to customize RSpec's
+behavior, including output formats, filtering examples, etc.
+
+For a full list of options, run the `rspec` command with the `--help` flag:
+
+```ruby
+$ rspec --help
+```
+
+### Run with `ruby`
+
+Generally, life is simpler if you just use the `rspec` command. If you must use
+the `ruby` command, however, you'll need to require `rspec/autorun`. You can
+either pass a `-rrspec/autorun` CLI option when invoking `ruby`, or add a
+`require 'rspec/autorun'` to one or more of your spec files.
+
+It is conventional to put configuration in and require assorted support files
+from `spec/spec_helper.rb`. It is also conventional to require that file from
+the spec files using `require 'spec_helper'`. This works because RSpec
+implicitly adds the `spec` directory to the `LOAD_PATH`. It also adds `lib`, so
+your implementation files will be on the `LOAD_PATH` as well.
+
+If you're using the `ruby` command, you'll need to do this yourself (with the
+`-I` option). Putting these together, your command might be something like this:
+
+```ruby
+$ ruby -Ilib -Ispec -rrspec/autorun path/to/spec.rb
+```
diff --git a/rspec-core/features/command_line/dry_run.feature b/rspec-core/features/command_line/dry_run.feature
new file mode 100644
index 0000000..b6cce9a
--- /dev/null
+++ b/rspec-core/features/command_line/dry_run.feature
@@ -0,0 +1,29 @@
+Feature: `--dry-run` option
+
+  Use the `--dry-run` option to have RSpec print your suite's formatter output
+  without running any examples or hooks.
+
+  Scenario: Using `--dry-run`
+    Given a file named "spec/dry_run_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.before(:suite) { puts "before suite" }
+        c.after(:suite)  { puts "after suite"  }
+      end
+
+      RSpec.describe "dry run" do
+        before(:context) { fail }
+        before(:example) { fail }
+
+        it "fails in example" do
+          fail
+        end
+
+        after(:example) { fail }
+        after(:context) { fail }
+      end
+      """
+    When I run `rspec --dry-run`
+    Then the output should contain "1 example, 0 failures"
+     And the output should not contain "before suite"
+     And the output should not contain "after suite"
diff --git a/rspec-core/features/command_line/example_name_option.feature b/rspec-core/features/command_line/example_name_option.feature
new file mode 100644
index 0000000..f41a9c9
--- /dev/null
+++ b/rspec-core/features/command_line/example_name_option.feature
@@ -0,0 +1,100 @@
+Feature: `--example` option
+
+  Use the `--example` (or `-e`) option to filter examples by name.
+
+  The argument is matched against the full description of the example, which is
+  the concatenation of descriptions of the group (including any nested groups)
+  and the example.
+
+  This allows you to run a single uniquely named example, all examples with
+  similar names, all the examples in a uniquely named group, etc, etc.
+
+  You can also use the option more than once to specify multiple example
+  matches.
+
+  Note: description-less examples that have generated descriptions (typical when using the [one-liner syntax](../subject/one-liner-syntax)) cannot be directly filtered with this option, because it is necessary to execute the example to generate the description, so RSpec is unable to use the not-yet-generated description to decide whether or not to execute an example. You can, of course, pass part of a group's description to select all examples defined in the group (including those that h [...]
+
+  Background:
+    Given a file named "first_spec.rb" with:
+      """ruby
+      RSpec.describe "first group" do
+        it "first example in first group" do; end
+        it "second example in first group" do; end
+      end
+      """
+    And a file named "second_spec.rb" with:
+      """ruby
+      RSpec.describe "second group" do
+        it "first example in second group" do; end
+        it "second example in second group" do; end
+      end
+      """
+    And a file named "third_spec.rb" with:
+      """ruby
+      RSpec.describe "third group" do
+        it "first example in third group" do; end
+        context "nested group" do
+          it "first example in nested group" do; end
+          it "second example in nested group" do; end
+        end
+      end
+      """
+    And a file named "fourth_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        describe "#length" do
+          it "is the number of items" do
+            expect(Array.new([1,2,3]).length).to eq 3
+          end
+        end
+      end
+      """
+
+  Scenario: No matches
+    When I run `rspec . --example nothing_like_this`
+    Then the process should succeed even though no examples were run
+
+  Scenario: Match on one word
+    When I run `rspec . --example example`
+    Then the examples should all pass
+
+  Scenario: One match in each context
+    When I run `rspec . --example 'first example'`
+    Then the examples should all pass
+
+  Scenario: One match in one file using just the example name
+    When I run `rspec . --example 'first example in first group'`
+    Then the examples should all pass
+
+  Scenario: One match in one file using the example name and the group name
+    When I run `rspec . --example 'first group first example in first group'`
+    Then the examples should all pass
+
+  Scenario: All examples in one group
+    When I run `rspec . --example 'first group'`
+    Then the examples should all pass
+
+  Scenario: One match in one file with group name
+    When I run `rspec . --example 'second group first example'`
+    Then the examples should all pass
+
+  Scenario: All examples in one group including examples in nested groups
+    When I run `rspec . --example 'third group'`
+    Then the examples should all pass
+
+  Scenario: Match using `ClassName#method_name` form
+    When I run `rspec . --example 'Array#length'`
+    Then the examples should all pass
+
+  Scenario: Multiple applications of example name option
+    When I run `rspec . --example 'first group' --example 'second group' --format d`
+    Then the examples should all pass
+    And the output should contain all of these:
+      |first example in first group|
+      |second example in first group|
+      |first example in second group|
+      |second example in second group|
+    And the output should not contain any of these:
+      |first example in third group|
+      |nested group first example in nested group|
+      |nested group second example in nested group|
diff --git a/rspec-core/features/command_line/exit_status.feature b/rspec-core/features/command_line/exit_status.feature
new file mode 100644
index 0000000..81b4c42
--- /dev/null
+++ b/rspec-core/features/command_line/exit_status.feature
@@ -0,0 +1,66 @@
+Feature: `--failure-exit-code` option (exit status)
+
+  The `rspec` command exits with an exit status of 0 if all examples pass, and 1
+  if any examples fail. The failure exit code can be overridden using the
+  `--failure-exit-code` option.
+
+  Scenario: A passing spec with the default exit code
+    Given a file named "ok_spec.rb" with:
+      """ruby
+      RSpec.describe "ok" do
+        it "passes" do
+        end
+      end
+      """
+    When I run `rspec ok_spec.rb`
+    Then the exit status should be 0
+    And the examples should all pass
+
+  Scenario: A failing spec with the default exit code
+    Given a file named "ko_spec.rb" with:
+      """ruby
+      RSpec.describe "KO" do
+        it "fails" do
+          raise "KO"
+        end
+      end
+      """
+    When I run `rspec ko_spec.rb`
+    Then the exit status should be 1
+    And the output should contain "1 example, 1 failure"
+
+  Scenario: A nested failing spec with the default exit code
+    Given a file named "nested_ko_spec.rb" with:
+      """ruby
+      RSpec.describe "KO" do
+        describe "nested" do
+          it "fails" do
+            raise "KO"
+          end
+        end
+      end
+      """
+    When I run `rspec nested_ko_spec.rb`
+    Then the exit status should be 1
+    And the output should contain "1 example, 1 failure"
+
+  Scenario: Exit with 0 when no examples are run
+    Given a file named "a_no_examples_spec.rb" with:
+      """ruby
+      """
+    When I run `rspec a_no_examples_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "0 examples"
+
+  Scenario: A failing spec and `--failure-exit-code` is 42
+    Given a file named "ko_spec.rb" with:
+      """ruby
+      RSpec.describe "KO" do
+        it "fails" do
+          raise "KO"
+        end
+      end
+      """
+    When I run `rspec --failure-exit-code 42 ko_spec.rb`
+    Then the exit status should be 42
+    And the output should contain "1 example, 1 failure"
diff --git a/rspec-core/features/command_line/fail_fast.feature b/rspec-core/features/command_line/fail_fast.feature
new file mode 100644
index 0000000..93d7dfc
--- /dev/null
+++ b/rspec-core/features/command_line/fail_fast.feature
@@ -0,0 +1,27 @@
+Feature: `--fail-fast` option
+
+  Use the `--fail-fast` option to tell RSpec to stop running the test suite on
+  the first failed test.
+
+  You may also specify `--no-fail-fast` to turn it off (default behaviour).
+
+  Background:
+    Given a file named "fail_fast_spec.rb" with:
+      """ruby
+      RSpec.describe "fail fast" do
+        it "passing test" do; end
+        it "failing test" do
+          fail
+        end
+        it "this should not be run" do; end
+      end
+      """
+
+  Scenario: Using `--fail-fast`
+    When I run `rspec . --fail-fast`
+    Then the output should contain ".F"
+    Then the output should not contain ".F."
+
+  Scenario: Using `--no-fail-fast`
+    When I run `rspec . --no-fail-fast`
+    Then the output should contain ".F."
diff --git a/rspec-core/features/command_line/format_option.feature b/rspec-core/features/command_line/format_option.feature
new file mode 100644
index 0000000..f6ed65f
--- /dev/null
+++ b/rspec-core/features/command_line/format_option.feature
@@ -0,0 +1,86 @@
+Feature: `--format` option
+
+  Use the `--format` option to tell RSpec how to format the output.
+
+  RSpec ships with several formatters built in. By default, it uses the progress
+  formatter, which generates output like this:
+
+      ....F.....*.....
+
+  A '.' represents a passing example, 'F' is failing, and '*' is pending.
+
+  Use the documentation formatter to see the documentation strings passed to
+  `describe`, `it`, and their aliases:
+
+  ```bash
+  $ rspec spec --format documentation
+  ```
+
+  You can also specify an output target (`$stdout` by default) with an `--out`
+  option immediately following the `--format` option:
+
+  ```bash
+  $ rspec spec --format documentation --out rspec.txt
+  ```
+
+  Run `rspec --help` to see a listing of available formatters.
+
+  Background:
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "does something that passes" do
+          expect(5).to eq(5)
+        end
+
+        it "does something that fails" do
+          expect(5).to eq(4)
+        end
+
+        it "does something that is pending", :pending => true do
+          expect(5).to be < 3
+        end
+
+        it "does something that is skipped", :skip => true do
+          expect(5).to be < 3
+        end
+      end
+      """
+
+  Scenario: Progress bar format (default)
+    When I run `rspec --format progress example_spec.rb`
+    Then the output should contain ".F**"
+
+  Scenario: Documentation format
+    When I run `rspec example_spec.rb --format documentation`
+    Then the output should contain:
+      """
+      something
+        does something that passes
+        does something that fails (FAILED - 1)
+        does something that is pending (PENDING: No reason given)
+        does something that is skipped (PENDING: No reason given)
+      """
+
+  Scenario: Documentation format saved to a file
+    When I run `rspec example_spec.rb --format documentation --out rspec.txt`
+    Then the file "rspec.txt" should contain:
+      """
+      something
+        does something that passes
+        does something that fails (FAILED - 1)
+        does something that is pending (PENDING: No reason given)
+        does something that is skipped (PENDING: No reason given)
+      """
+
+  Scenario: Multiple formats and output targets
+    When I run `rspec example_spec.rb --format progress --format documentation --out rspec.txt`
+    Then the output should contain ".F**"
+    And the file "rspec.txt" should contain:
+      """
+      something
+        does something that passes
+        does something that fails (FAILED - 1)
+        does something that is pending (PENDING: No reason given)
+        does something that is skipped (PENDING: No reason given)
+      """
diff --git a/rspec-core/features/command_line/init.feature b/rspec-core/features/command_line/init.feature
new file mode 100644
index 0000000..44fe401
--- /dev/null
+++ b/rspec-core/features/command_line/init.feature
@@ -0,0 +1,50 @@
+Feature: `--init` option
+
+  Use the `--init` option on the command line to generate conventional files for
+  an RSpec project. It generates a `.rspec` and `spec/spec_helper.rb` with some
+  example settings to get you started.
+
+  These settings treat the case where you run an individual spec file
+  differently, using the documentation formatter if no formatter has been
+  explicitly set.
+
+  Scenario: Generate `.rspec`
+    When I run `rspec --init`
+    Then the following files should exist:
+      | .rspec |
+    And the output should contain "create   .rspec"
+
+  Scenario: `.rspec` file already exists
+    Given a file named ".rspec" with:
+      """
+      --color
+      """
+    When I run `rspec --init`
+    Then the output should contain "exist   .rspec"
+
+  Scenario: Accept and use the recommended settings in `spec_helper` (which are initially commented out)
+    Given I have a brand new project with no files
+      And I have run `rspec --init`
+     When I accept the recommended settings by removing `=begin` and `=end` from `spec/spec_helper.rb`
+      And I create "spec/addition_spec.rb" with the following content:
+        """ruby
+        RSpec.describe "Addition" do
+          it "works" do
+            expect(1 + 1).to eq(2)
+          end
+        end
+        """
+      And I create "spec/subtraction_spec.rb" with the following content:
+        """ruby
+        RSpec.describe "Subtraction" do
+          it "works" do
+            expect(1 - 1).to eq(0)
+          end
+        end
+        """
+     Then the output from `rspec` should not be in documentation format
+      But the output from `rspec spec/addition_spec.rb` should be in documentation format
+      But the output from `rspec spec/addition_spec.rb --format progress` should not be in documentation format
+
+      And the output from `rspec --pattern 'spec/*ction_spec.rb'` should indicate it ran only the subtraction file
+      And the output from `rspec --exclude-pattern 'spec/*dition_spec.rb'` should indicate it ran only the subtraction file
diff --git a/rspec-core/features/command_line/line_number_appended_to_path.feature b/rspec-core/features/command_line/line_number_appended_to_path.feature
new file mode 100644
index 0000000..32b70f2
--- /dev/null
+++ b/rspec-core/features/command_line/line_number_appended_to_path.feature
@@ -0,0 +1,159 @@
+Feature: line number appended to file path
+
+  To run one or more examples or groups, you can append the line number to the
+  path, e.g.
+
+  ```bash
+  $ rspec path/to/example_spec.rb:37
+  ```
+
+  Background:
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "outer group" do
+
+        it "first example in outer group" do
+
+        end
+
+        it "second example in outer group" do
+
+        end
+
+        describe "nested group" do
+
+          it "example in nested group" do
+
+          end
+
+        end
+
+      end
+      """
+    And a file named "example2_spec.rb" with:
+      """ruby
+      RSpec.describe "yet another group" do
+        it "first example in second file" do
+        end
+        it "second example in second file" do
+        end
+      end
+      """
+    And a file named "one_liner_spec.rb" with:
+      """ruby
+      RSpec.describe 9 do
+
+        it { is_expected.to be > 8 }
+
+        it { is_expected.to be < 10 }
+
+      end
+      """
+
+  Scenario: Nested groups - outer group on declaration line
+    When I run `rspec example_spec.rb:1 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    And the output should contain "first example in outer group"
+    And the output should contain "example in nested group"
+
+  Scenario: Nested groups - outer group inside block before example
+    When I run `rspec example_spec.rb:2 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    And the output should contain "first example in outer group"
+    And the output should contain "example in nested group"
+
+  Scenario: Nested groups - inner group on declaration line
+    When I run `rspec example_spec.rb:11 --format doc`
+    Then the examples should all pass
+    And the output should contain "example in nested group"
+    And the output should not contain "second example in outer group"
+    And the output should not contain "first example in outer group"
+
+  Scenario: Nested groups - inner group inside block before example
+    When I run `rspec example_spec.rb:12 --format doc`
+    Then the examples should all pass
+    And the output should contain "example in nested group"
+    And the output should not contain "second example in outer group"
+    And the output should not contain "first example in outer group"
+
+  Scenario: Two examples - first example on declaration line
+    When I run `rspec example_spec.rb:3 --format doc`
+    Then the examples should all pass
+    And the output should contain "first example in outer group"
+    But the output should not contain "second example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Two examples - first example inside block
+    When I run `rspec example_spec.rb:4 --format doc`
+    Then the examples should all pass
+    And the output should contain "first example in outer group"
+    But the output should not contain "second example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Two examples - first example on end
+    When I run `rspec example_spec.rb:5 --format doc`
+    Then the examples should all pass
+    And the output should contain "first example in outer group"
+    But the output should not contain "second example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Two examples - first example after end but before next example
+    When I run `rspec example_spec.rb:6 --format doc`
+    Then the examples should all pass
+    And the output should contain "first example in outer group"
+    But the output should not contain "second example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Two examples - second example on declaration line
+    When I run `rspec example_spec.rb:7 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    But the output should not contain "first example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Two examples - second example inside block
+    When I run `rspec example_spec.rb:7 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    But the output should not contain "first example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Two examples - second example on end
+    When I run `rspec example_spec.rb:7 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    But the output should not contain "first example in outer group"
+    And the output should not contain "example in nested group"
+
+  Scenario: Specified multiple times for different files
+    When I run `rspec example_spec.rb:7 example2_spec.rb:4 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    And the output should contain "second example in second file"
+    But the output should not contain "first example in outer group"
+    And the output should not contain "nested group"
+    And the output should not contain "first example in second file"
+
+  Scenario: Specified multiple times for the same file with multiple arguments
+    When I run `rspec example_spec.rb:7 example_spec.rb:11 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    And the output should contain "nested group"
+    But the output should not contain "first example in outer group"
+    And the output should not contain "second file"
+
+  Scenario: Specified multiple times for the same file with a single argument
+    When I run `rspec example_spec.rb:7:11 --format doc`
+    Then the examples should all pass
+    And the output should contain "second example in outer group"
+    And the output should contain "nested group"
+    But the output should not contain "first example in outer group"
+    And the output should not contain "second file"
+
+  Scenario: Matching one-liners
+    When I run `rspec one_liner_spec.rb:3 --format doc`
+    Then the examples should all pass
+    Then the output should contain "should be > 8"
+    But the output should not contain "should be < 10"
diff --git a/rspec-core/features/command_line/order.md b/rspec-core/features/command_line/order.md
new file mode 100644
index 0000000..92eeb28
--- /dev/null
+++ b/rspec-core/features/command_line/order.md
@@ -0,0 +1,25 @@
+Use the `--order` option to tell RSpec how to order the files, groups, and
+examples. The available ordering schemes are `defined` and `rand`.
+
+`defined` is the default, which executes groups and examples in the order they
+are defined as the spec files are loaded, with the caveat that each group
+runs its examples before running its nested example groups, even if the
+nested groups are defined before the examples.
+
+Use `rand` to randomize the order of groups and examples within the groups.
+Nested groups are always run from top-level to bottom-level in order to avoid
+executing `before(:context)` and `after(:context)` hooks more than once, but the
+order of groups at each level is randomized.
+
+With `rand` you can also specify a seed.
+
+## Example usage
+
+The `defined` option is only necessary when you have `--order rand` stored in a
+config file (e.g. `.rspec`) and you want to override it from the command line.
+
+<pre><code class="bash">--order defined
+--order rand
+--order rand:123
+--seed 123 # same as --order rand:123
+</code></pre>
diff --git a/rspec-core/features/command_line/pattern_option.feature b/rspec-core/features/command_line/pattern_option.feature
new file mode 100644
index 0000000..3d3bce2
--- /dev/null
+++ b/rspec-core/features/command_line/pattern_option.feature
@@ -0,0 +1,42 @@
+Feature: `--pattern` option
+
+  By default, RSpec loads files matching the pattern:
+
+      "spec/**/*_spec.rb"
+
+  Use the `--pattern` option to declare a different pattern.
+
+  Background:
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "two specs" do
+        it "passes" do
+        end
+
+        it "passes too" do
+        end
+      end
+      """
+    And a file named "spec/example_test.rb" with:
+      """ruby
+      RSpec.describe "one spec" do
+        it "passes" do
+        end
+      end
+      """
+
+  Scenario: By default, RSpec runs files that match `"**/*_spec.rb"`
+   When I run `rspec`
+   Then the output should contain "2 examples, 0 failures"
+
+  Scenario: The `--pattern` flag makes RSpec run files matching the specified pattern and ignore the default pattern
+   When I run `rspec -P "**/*_test.rb"`
+   Then the output should contain "1 example, 0 failures"
+
+  Scenario: The `--pattern` flag can be used to pass in multiple patterns, separated by commas
+   When I run `rspec -P "**/*_test.rb,**/*_spec.rb"`
+   Then the output should contain "3 examples, 0 failures"
+
+  Scenario: The `--pattern` flag accepts shell style glob unions
+   When I run `rspec -P "**/*_{test,spec}.rb"`
+   Then the output should contain "3 examples, 0 failures"
diff --git a/rspec-core/features/command_line/rake_task.feature b/rspec-core/features/command_line/rake_task.feature
new file mode 100644
index 0000000..bb2fb01
--- /dev/null
+++ b/rspec-core/features/command_line/rake_task.feature
@@ -0,0 +1,158 @@
+Feature: rake task
+
+  RSpec ships with a rake task with a number of useful options.
+
+  We recommend you wrap this in a `rescue` clause so that you can
+  use your `Rakefile` in an environment where RSpec is unavailable
+  (for example on a production server). e.g:
+
+  ```ruby
+  begin
+    require 'rspec/core/rake_task'
+    RSpec::Core::RakeTask.new(:spec)
+  rescue LoadError
+  end
+  ```
+
+  Scenario: Default options with passing spec (prints command and exit status is 0)
+    Given a file named "Rakefile" with:
+      """ruby
+
+      begin
+        require 'rspec/core/rake_task'
+
+        RSpec::Core::RakeTask.new(:spec)
+
+        task :default => :spec
+      rescue LoadError
+        # no rspec available
+      end
+      """
+    And a file named "spec/thing_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "does something" do
+          # pass
+        end
+      end
+      """
+    When I run `rake`
+    Then the output should match:
+      """
+      (ruby|rbx) -I\S+ [\/\S]+\/exe\/rspec
+      """
+    Then the exit status should be 0
+
+  Scenario: Default options with failing spec (exit status is 1)
+    Given a file named "Rakefile" with:
+      """ruby
+      begin
+        require 'rspec/core/rake_task'
+
+        RSpec::Core::RakeTask.new(:spec)
+
+        task :default => :spec
+      rescue LoadError
+        # no rspec available
+      end
+      """
+    And a file named "spec/thing_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "does something" do
+          fail
+        end
+      end
+      """
+    When I run `rake`
+    Then the exit status should be 1
+
+  Scenario: Setting `fail_on_error = false` with failing spec (exit status is 0)
+    Given a file named "Rakefile" with:
+      """ruby
+      begin
+        require 'rspec/core/rake_task'
+
+        RSpec::Core::RakeTask.new(:spec) do |t|
+          t.fail_on_error = false
+        end
+
+        task :default => :spec
+      rescue LoadError
+        # no rspec available
+      end
+      """
+    And a file named "spec/thing_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "does something" do
+          fail
+        end
+      end
+      """
+    When I run `rake`
+    Then the exit status should be 0
+
+  Scenario: Passing arguments to the `rspec` command using `rspec_opts`
+    Given a file named "Rakefile" with:
+      """ruby
+      begin
+        require 'rspec/core/rake_task'
+
+        RSpec::Core::RakeTask.new(:spec) do |t|
+          t.rspec_opts = "--tag fast"
+        end
+      rescue LoadError
+        # no rspec available
+      end
+      """
+    And a file named "spec/thing_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "has a tag", :fast => true do
+          # pass
+        end
+
+        it "does not have a tag" do
+          fail
+        end
+      end
+      """
+    When I run `rake spec`
+    Then the exit status should be 0
+    Then the output should match:
+      """
+      (ruby|rbx) -I\S+ [\/\S]+\/exe\/rspec --pattern spec[\/\\*{,}]+_spec.rb --tag fast
+      """
+
+  Scenario: Passing rake task arguments to the `rspec` command via `rspec_opts`
+    Given a file named "Rakefile" with:
+      """ruby
+      begin
+        require 'rspec/core/rake_task'
+
+        RSpec::Core::RakeTask.new(:spec, :tag) do |t, task_args|
+          t.rspec_opts = "--tag #{task_args[:tag]}"
+        end
+      rescue LoadError
+        # no rspec available
+      end
+      """
+    And a file named "spec/thing_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "has a tag", :fast => true do
+          # pass
+        end
+
+        it "does not have a tag" do
+          fail
+        end
+      end
+      """
+    When I run `rake spec[fast]`
+    Then the exit status should be 0
+    Then the output should match:
+      """
+      (ruby|rbx) -I\S+ [\/\S]+\/exe\/rspec --pattern spec[\/\\*{,}]+_spec.rb --tag fast
+      """
diff --git a/rspec-core/features/command_line/randomization.feature b/rspec-core/features/command_line/randomization.feature
new file mode 100644
index 0000000..f975334
--- /dev/null
+++ b/rspec-core/features/command_line/randomization.feature
@@ -0,0 +1,65 @@
+Feature: Randomization can be reproduced across test runs
+
+  In Ruby, randomness is seeded by calling `srand` and passing it the seed that
+  you want to use. By doing this, subsequent calls to `rand`, `shuffle`,
+  `sample`, etc. will all be randomized the same way given the same seed is
+  passed to `srand`.
+
+  RSpec takes care not to seed randomization directly when taking action that
+  involves randomness (such as random ordering of examples).
+
+  Since RSpec does not ever invoke `srand`, this means that you are free to
+  choose which, if any, mechanism is used to seed randomization.
+
+  There is an example below of how to use RSpec's seed for this purpose if you
+  wish to do so.
+
+  If you would like to manage seeding randomization without any help from RSpec,
+  please keep the following things in mind:
+
+    * The seed should never be hard-coded.
+
+      The first example below only does this to show that seeding randomization
+      with a seed other than the one used by RSpec will correctly seed
+      randomization.
+
+    * Report the seed that was chosen.
+
+      The randomization that was used for a given test run can not be reproduced
+      if no one knows what seed was used to begin with.
+
+    * Provide a mechanism to feed the seed into the tests.
+
+      Without this, the call to `srand` will have to be hard-coded any time it
+      is necessary to replicate a given test run's randomness.
+
+  Background:
+    Given a file named ".rspec" with:
+      """
+      --require spec_helper
+      """
+
+    Given a file named "spec/random_spec.rb" with:
+      """ruby
+      RSpec.describe 'randomized example' do
+        it 'prints random numbers' do
+          puts 5.times.map { rand(99) }.join("-")
+        end
+      end
+      """
+
+  Scenario: Specifying a seed using `srand` provides predictable randomization
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      srand 123
+      """
+    When I run `rspec`
+    Then the output should contain "66-92-98-17-83"
+
+  Scenario: Passing the RSpec seed to `srand` provides predictable randomization
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      srand RSpec.configuration.seed
+      """
+    When I run `rspec --seed 123`
+    Then the output should contain "66-92-98-17-83"
diff --git a/rspec-core/features/command_line/require_option.feature b/rspec-core/features/command_line/require_option.feature
new file mode 100644
index 0000000..29b8c7e
--- /dev/null
+++ b/rspec-core/features/command_line/require_option.feature
@@ -0,0 +1,45 @@
+Feature: `--require` option
+
+  Use the `--require` (or `-r`) option to specify a file to require before
+  running specs.
+
+  Scenario: Using the `--require` option
+    Given a file named "logging_formatter.rb" with:
+      """ruby
+      require "rspec/core/formatters/base_text_formatter"
+      require 'delegate'
+
+      class LoggingFormatter < RSpec::Core::Formatters::BaseTextFormatter
+        RSpec::Core::Formatters.register self, :dump_summary
+
+        def initialize(output)
+          super LoggingIO.new(output)
+        end
+
+        class LoggingIO < SimpleDelegator
+          def initialize(output)
+            @file = File.new('rspec.log', 'w')
+            super
+          end
+
+          def puts(*args)
+            [@file, __getobj__].each { |out| out.puts(*args) }
+          end
+
+          def close
+            @file.close
+          end
+        end
+      end
+      """
+    And a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "an embarassing situation" do
+        it "happens to everyone" do
+        end
+      end
+      """
+    When I run `rspec --require ./logging_formatter.rb --format LoggingFormatter`
+    Then the output should contain "1 example, 0 failures"
+    And  the file "rspec.log" should contain "1 example, 0 failures"
+    And  the exit status should be 0
diff --git a/rspec-core/features/command_line/ruby.feature b/rspec-core/features/command_line/ruby.feature
new file mode 100644
index 0000000..d0e50ba
--- /dev/null
+++ b/rspec-core/features/command_line/ruby.feature
@@ -0,0 +1,27 @@
+Feature: run with `ruby` command
+
+  You can use the `ruby` command to run specs. You just need to require
+  `rspec/autorun`.
+
+  Generally speaking, you're better off using the `rspec` command, which avoids
+  the complexity of `rspec/autorun` (e.g. no `at_exit` hook needed!), but some
+  tools only work with the `ruby` command.
+
+  Scenario: Require `rspec/autorun` from a spec file
+    Given a file named "example_spec.rb" with:
+      """ruby
+      require 'rspec/autorun'
+
+      RSpec.describe 1 do
+        it "is < 2" do
+          expect(1).to be < 2
+        end
+
+        it "has an intentional failure" do
+          expect(1).to be > 2
+        end
+      end
+      """
+    When I run `ruby example_spec.rb`
+    Then the output should contain "2 examples, 1 failure"
+     And the output should contain "expect(1).to be > 2"
diff --git a/rspec-core/features/command_line/tag.feature b/rspec-core/features/command_line/tag.feature
new file mode 100644
index 0000000..14fdb89
--- /dev/null
+++ b/rspec-core/features/command_line/tag.feature
@@ -0,0 +1,102 @@
+Feature: `--tag` option
+
+  Use the `--tag` (or `-t`) option to filter the examples by tags.
+
+  The tag can be a simple `name` or a `name:value` pair. In the first case,
+  examples with `:name => true` will be filtered. In the second case, examples
+  with `:name => value` will be filtered, where `value` is always a string. In
+  both cases, `name` is converted to a symbol.
+
+  Filters are represented internally as a hash, which means that you can't
+  specify multiple filters for the same key. If you try to exclude `:name => 'foo'`
+  and `:name => 'bar'`, you will only end up excluding `:name => 'bar'`.
+
+  Tags can also be used to exclude examples by adding a `~` before the tag. For
+  example `~tag` will exclude all examples marked with `:tag => true` and
+  `~tag:value` will exclude all examples marked with `:tag => value`.
+
+  To be compatible with the Cucumber syntax, tags can optionally start with an
+  `@` symbol, which will be ignored.
+
+  Background:
+    Given a file named "tagged_spec.rb" with:
+      """ruby
+      RSpec.describe "group with tagged specs" do
+        it "example I'm working now", :focus => true do; end
+        it "special example with string", :type => 'special' do; end
+        it "special example with symbol", :type => :special do; end
+        it "slow example", :skip => true do; end
+        it "ordinary example", :speed => 'slow' do; end
+        it "untagged example" do; end
+      end
+      """
+
+  Scenario: Filter examples with non-existent tag
+    When I run `rspec . --tag mytag`
+    Then the process should succeed even though no examples were run
+
+  Scenario: Filter examples with a simple tag
+    When I run `rspec . --tag focus`
+    Then the output should contain "include {:focus=>true}"
+    And the examples should all pass
+
+  Scenario: Filter examples with a simple tag and @
+    When I run `rspec . --tag @focus`
+    Then the output should contain "include {:focus=>true}"
+    Then the examples should all pass
+
+  Scenario: Filter examples with a `name:value` tag
+    When I run `rspec . --tag type:special`
+    Then the output should contain:
+      """
+      include {:type=>"special"}
+      """
+    And the output should contain "2 examples"
+    And the examples should all pass
+
+  Scenario: Filter examples with a `name:value` tag and @
+    When I run `rspec . --tag @type:special`
+    Then the output should contain:
+      """
+      include {:type=>"special"}
+      """
+    And the examples should all pass
+
+  Scenario: Exclude examples with a simple tag
+    When I run `rspec . --tag ~skip`
+    Then the output should contain "exclude {:skip=>true}"
+    Then the examples should all pass
+
+  Scenario: Exclude examples with a simple tag and @
+    When I run `rspec . --tag ~@skip`
+    Then the output should contain "exclude {:skip=>true}"
+    Then the examples should all pass
+
+  Scenario: Exclude examples with a `name:value` tag
+    When I run `rspec . --tag ~speed:slow`
+    Then the output should contain:
+      """
+      exclude {:speed=>"slow"}
+      """
+    Then the examples should all pass
+
+  Scenario: Exclude examples with a `name:value` tag and @
+    When I run `rspec . --tag ~@speed:slow`
+    Then the output should contain:
+      """
+      exclude {:speed=>"slow"}
+      """
+    Then the examples should all pass
+
+  Scenario: Filter examples with a simple tag, exclude examples with another tag
+    When I run `rspec . --tag focus --tag ~skip`
+    Then the output should contain "include {:focus=>true}"
+    And the output should contain "exclude {:skip=>true}"
+    And the examples should all pass
+
+  Scenario: Exclude examples with multiple tags
+    When I run `rspec . --tag ~skip --tag ~speed:slow`
+    Then the output should contain one of the following:
+      | exclude {:skip=>true, :speed=>"slow"} |
+      | exclude {:speed=>"slow", :skip=>true} |
+    Then the examples should all pass
diff --git a/rspec-core/features/command_line/warnings_option.feature b/rspec-core/features/command_line/warnings_option.feature
new file mode 100644
index 0000000..ab69507
--- /dev/null
+++ b/rspec-core/features/command_line/warnings_option.feature
@@ -0,0 +1,29 @@
+Feature: `--warnings` option (run with warnings enabled)
+
+  You can use the `--warnings` option to run specs with warnings enabled
+
+  @unsupported-on-rbx
+  Scenario:
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe do
+        it 'generates warning' do
+          @undefined
+        end
+      end
+      """
+    When I run `rspec --warnings example_spec.rb`
+    Then the output should contain "warning"
+
+  @unsupported-on-rbx
+  Scenario:
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe do
+        it 'generates warning' do
+          @undefined
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should not contain "warning"
diff --git a/rspec-core/features/configuration/alias_example_to.feature b/rspec-core/features/configuration/alias_example_to.feature
new file mode 100644
index 0000000..403e397
--- /dev/null
+++ b/rspec-core/features/configuration/alias_example_to.feature
@@ -0,0 +1,57 @@
+Feature: Create example aliases
+
+  Use `config.alias_example_to` to create new example group methods that define
+  examples with the configured metadata. You can also specify metadata using
+  only symbols.
+
+  Scenario: Use `alias_example_to` to define a custom example name
+    Given a file named "alias_example_to_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.alias_example_to :task
+      end
+
+      RSpec.describe "a task example group" do
+        task "does something" do
+          expect(5).to eq(5)
+        end
+      end
+      """
+    When I run `rspec alias_example_to_spec.rb --format doc`
+    Then the output should contain "does something"
+    And the examples should all pass
+
+
+  Scenario: Use `alias_example_to` to define a pending example
+    Given a file named "alias_example_to_pending_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.alias_example_to :pit, :pending => "Pit alias used"
+      end
+
+      RSpec.describe "an example group" do
+        pit "does something later on" do
+          fail "not implemented yet"
+        end
+      end
+      """
+    When I run `rspec alias_example_to_pending_spec.rb --format doc`
+    Then the output should contain "does something later on (PENDING: Pit alias used)"
+    And the output should contain "0 failures"
+
+  Scenario: Use symbols as metadata
+    Given a file named "use_symbols_as_metadata_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.alias_example_to :pit, :pending
+      end
+
+      RSpec.describe "an example group" do
+        pit "does something later on" do
+          fail "not implemented yet"
+        end
+      end
+      """
+    When I run `rspec use_symbols_as_metadata_spec.rb --format doc`
+    Then the output should contain "does something later on (PENDING: No reason given)"
+    And the output should contain "0 failures"
diff --git a/rspec-core/features/configuration/backtrace_exclusion_patterns.feature b/rspec-core/features/configuration/backtrace_exclusion_patterns.feature
new file mode 100644
index 0000000..4a87469
--- /dev/null
+++ b/rspec-core/features/configuration/backtrace_exclusion_patterns.feature
@@ -0,0 +1,154 @@
+Feature: Excluding lines from the backtrace
+
+  To reduce the noise when diagnosing failures, RSpec can exclude lines belonging to certain gems or matching given patterns.
+
+  If you want to filter out backtrace lines belonging to specific gems, you can use `config.filter_gems_from_backtrace` like so:
+
+  ```ruby
+  config.filter_gems_from_backtrace "ignored_gem", "another_ignored_gem",
+  ```
+
+  For more control over which lines to ignore, you can use the the `backtrace_exclusion_patterns` option to either replace the default exclusion patterns, or append your own, e.g.
+
+  ```ruby
+  config.backtrace_exclusion_patterns = [/first pattern/, /second pattern/]
+  config.backtrace_exclusion_patterns << /another pattern/
+  ```
+
+  The default exclusion patterns are:
+
+  ```ruby
+  /\/lib\d*\/ruby\//,
+  /org\/jruby\//,
+  /bin\//,
+  /lib\/rspec\/(core|expectations|matchers|mocks)/
+  ```
+
+  Additionally, `rspec` can be run with the `--backtrace` option to skip backtrace cleaning entirely.
+
+
+  Scenario: Using default `backtrace_exclusion_patterns`
+    Given a file named "spec/failing_spec.rb" with:
+    """ruby
+    RSpec.describe "2 + 2" do
+      it "is 5" do
+        expect(2+2).to eq(5)
+      end
+    end
+    """
+    When I run `rspec`
+    Then the output should contain "1 example, 1 failure"
+    And the output should not contain "lib/rspec/expectations"
+
+  Scenario: Replacing `backtrace_exclusion_patterns`
+    Given a file named "spec/spec_helper.rb" with:
+    """ruby
+    RSpec.configure do |config|
+      config.backtrace_exclusion_patterns = [
+        /spec_helper/
+      ]
+    end
+    """
+    And a file named "spec/example_spec.rb" with:
+    """ruby
+    require 'spec_helper'
+    RSpec.describe "foo" do
+      it "returns baz" do
+        expect("foo").to eq("baz")
+      end
+    end
+    """
+    When I run `rspec`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "lib/rspec/expectations"
+
+  Scenario: Appending to `backtrace_exclusion_patterns`
+    Given a file named "spec/support/assert_baz.rb" with:
+    """ruby
+    require "support/really_assert_baz"
+
+    def assert_baz(arg)
+      really_assert_baz(arg)
+    end
+    """
+    And a file named "spec/support/really_assert_baz.rb" with:
+    """ruby
+    def really_assert_baz(arg)
+      expect(arg).to eq("baz")
+    end
+    """
+    And a file named "spec/example_spec.rb" with:
+    """ruby
+    require "support/assert_baz"
+    RSpec.configure do |config|
+      config.backtrace_exclusion_patterns << /really/
+    end
+
+    RSpec.describe "bar" do
+      it "is baz" do
+        assert_baz("bar")
+      end
+    end
+    """
+    When I run `rspec`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "assert_baz"
+    But the output should not contain "really_assert_baz"
+    And the output should not contain "lib/rspec/expectations"
+
+  Scenario: Running `rspec` with `--backtrace` prints unfiltered backtraces
+    Given a file named "spec/support/custom_helper.rb" with:
+    """ruby
+    def assert_baz(arg)
+      expect(arg).to eq("baz")
+    end
+    """
+    And a file named "spec/example_spec.rb" with:
+    """ruby
+    require "support/custom_helper"
+
+    RSpec.configure do |config|
+      config.backtrace_exclusion_patterns << /custom_helper/
+    end
+
+    RSpec.describe "bar" do
+      it "is baz" do
+        assert_baz("bar")
+      end
+    end
+    """
+    When I run `rspec --backtrace`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "spec/support/custom_helper.rb:2:in `assert_baz'"
+    And the output should contain "lib/rspec/expectations"
+    And the output should contain "lib/rspec/core"
+
+  Scenario: Using `filter_gems_from_backtrace` to filter the named gem
+    Given a vendored gem named "my_gem" containing a file named "lib/my_gem.rb" with:
+      """ruby
+      class MyGem
+        def self.do_amazing_things!
+          # intentional bug to trigger an exception
+          impossible_math = 10 / 0
+          "10 div 0 is: #{impossible_math}"
+        end
+      end
+      """
+    And a file named "spec/use_my_gem_spec.rb" with:
+      """ruby
+      require 'my_gem'
+
+      RSpec.describe "Using my_gem" do
+        it 'does amazing things' do
+          expect(MyGem.do_amazing_things!).to include("10 div 0 is")
+        end
+      end
+      """
+    And a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.filter_gems_from_backtrace "my_gem"
+      end
+      """
+    Then the output from `rspec` should contain "vendor/my_gem-1.2.3/lib/my_gem.rb:4:in `do_amazing_things!'"
+    But the output from `rspec --require spec_helper` should not contain "vendor/my_gem-1.2.3/lib/my_gem.rb:4:in `do_amazing_things!'"
diff --git a/rspec-core/features/configuration/custom_settings.feature b/rspec-core/features/configuration/custom_settings.feature
new file mode 100644
index 0000000..6540da6
--- /dev/null
+++ b/rspec-core/features/configuration/custom_settings.feature
@@ -0,0 +1,84 @@
+Feature: custom settings
+
+  Extensions like rspec-rails can add their own configuration settings.
+
+  Scenario: Simple setting (with defaults)
+    Given a file named "additional_setting_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.add_setting :custom_setting
+      end
+
+      RSpec.describe "custom setting" do
+        it "is nil by default" do
+          expect(RSpec.configuration.custom_setting).to be_nil
+        end
+
+        it "acts false by default" do
+          expect(RSpec.configuration.custom_setting).to be_falsey
+        end
+
+        it "is exposed as a predicate" do
+          expect(RSpec.configuration.custom_setting?).to be_falsey
+        end
+
+        it "can be overridden" do
+          RSpec.configuration.custom_setting = true
+          expect(RSpec.configuration.custom_setting).to be_truthy
+          expect(RSpec.configuration.custom_setting?).to be_truthy
+        end
+      end
+      """
+    When I run `rspec ./additional_setting_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Default to `true`
+    Given a file named "additional_setting_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.add_setting :custom_setting, :default => true
+      end
+
+      RSpec.describe "custom setting" do
+        it "is true by default" do
+          expect(RSpec.configuration.custom_setting).to be_truthy
+        end
+
+        it "is exposed as a predicate" do
+          expect(RSpec.configuration.custom_setting?).to be_truthy
+        end
+
+        it "can be overridden" do
+          RSpec.configuration.custom_setting = false
+          expect(RSpec.configuration.custom_setting).to be_falsey
+          expect(RSpec.configuration.custom_setting?).to be_falsey
+        end
+      end
+      """
+    When I run `rspec ./additional_setting_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Overridden in a subsequent `RSpec.configure` block
+    Given a file named "additional_setting_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.add_setting :custom_setting
+      end
+
+      RSpec.configure do |c|
+        c.custom_setting = true
+      end
+
+      RSpec.describe "custom setting" do
+        it "returns the value set in the last cofigure block to get eval'd" do
+          expect(RSpec.configuration.custom_setting).to be_truthy
+        end
+
+        it "is exposed as a predicate" do
+          expect(RSpec.configuration.custom_setting?).to be_truthy
+        end
+      end
+      """
+    When I run `rspec ./additional_setting_spec.rb`
+    Then the examples should all pass
+
diff --git a/rspec-core/features/configuration/default_path.feature b/rspec-core/features/configuration/default_path.feature
new file mode 100644
index 0000000..b0fb468
--- /dev/null
+++ b/rspec-core/features/configuration/default_path.feature
@@ -0,0 +1,37 @@
+Feature: Setting the default spec path
+
+  You can just type `rspec` to run all specs that live in the `spec` directory.
+
+  This is supported by a `--default-path` option, which is set to `spec` by
+  default. If you prefer to keep your specs in a different directory, or assign
+  an individual file to `--default-path`, you can do so on the command line or
+  in a configuration file (`.rspec`, `~/.rspec`, or a custom file).
+
+  **NOTE:** this option is not supported on `RSpec.configuration`, as it needs to be
+  set before spec files are loaded.
+
+  Scenario: Run `rspec` with default `default-path` (`spec` directory)
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        it "passes" do
+        end
+      end
+      """
+    When I run `rspec`
+    Then the output should contain "1 example, 0 failures"
+
+  Scenario: Run `rspec` with customized `default-path`
+    Given a file named ".rspec" with:
+      """
+      --default-path behavior
+      """
+    Given a file named "behavior/example_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        it "passes" do
+        end
+      end
+      """
+    When I run `rspec`
+    Then the output should contain "1 example, 0 failures"
diff --git a/rspec-core/features/configuration/deprecation_stream.feature b/rspec-core/features/configuration/deprecation_stream.feature
new file mode 100644
index 0000000..187651e
--- /dev/null
+++ b/rspec-core/features/configuration/deprecation_stream.feature
@@ -0,0 +1,87 @@
+Feature: Custom deprecation stream
+
+  Define a custom output stream for warning about deprecations (default
+  `$stderr`).
+
+  ```ruby
+  RSpec.configure do |c|
+    c.deprecation_stream = File.open('deprecations.txt', 'w')
+  end
+  ```
+
+  or
+
+  ```ruby
+  RSpec.configure { |c| c.deprecation_stream = 'deprecations.txt' }
+  ```
+
+  or pass `--deprecation-out`
+
+  Background:
+    Given a file named "lib/foo.rb" with:
+      """ruby
+      class Foo
+        def bar
+          RSpec.deprecate "Foo#bar"
+        end
+      end
+      """
+
+  Scenario: Default - print deprecations to `$stderr`
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "foo"
+
+      RSpec.describe "calling a deprecated method" do
+        example { Foo.new.bar }
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the output should contain "Deprecation Warnings:\n\nFoo#bar is deprecated"
+
+  Scenario: Configure using the path to a file
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "foo"
+
+      RSpec.configure {|c| c.deprecation_stream = 'deprecations.txt' }
+
+      RSpec.describe "calling a deprecated method" do
+        example { Foo.new.bar }
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the output should not contain "Deprecation Warnings:"
+    But the output should contain "1 deprecation logged to deprecations.txt"
+    And the file "deprecations.txt" should contain "Foo#bar is deprecated"
+
+  Scenario: Configure using a `File` object
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "foo"
+
+      RSpec.configure do |c|
+        c.deprecation_stream = File.open('deprecations.txt', 'w')
+      end
+
+      RSpec.describe "calling a deprecated method" do
+        example { Foo.new.bar }
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the output should not contain "Deprecation Warnings:"
+    But the output should contain "1 deprecation logged to deprecations.txt"
+    And the file "deprecations.txt" should contain "Foo#bar is deprecated"
+
+  Scenario: configure using the CLI `--deprecation-out` option
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "foo"
+      RSpec.describe "calling a deprecated method" do
+        example { Foo.new.bar }
+      end
+      """
+    When I run `rspec spec/example_spec.rb --deprecation-out deprecations.txt`
+    Then the output should not contain "Deprecation Warnings:"
+    But the output should contain "1 deprecation logged to deprecations.txt"
+    And the file "deprecations.txt" should contain "Foo#bar is deprecated"
diff --git a/rspec-core/features/configuration/enable_global_dsl.feature b/rspec-core/features/configuration/enable_global_dsl.feature
new file mode 100644
index 0000000..3009c80
--- /dev/null
+++ b/rspec-core/features/configuration/enable_global_dsl.feature
@@ -0,0 +1,60 @@
+Feature: Global namespace DSL
+
+  RSpec has a few top-level constructs that allow you to begin describing
+  behaviour:
+
+  * `RSpec.describe`: Define a named context for a group of examples.
+
+  * `RSpec.shared_examples`: Define a set of shared examples that can later be
+    included in an example group.
+
+  * `RSpec.shared_context`: define some common context (using `before`, `let`,
+    helper methods, etc) that can later be included in an example group.
+
+  Historically, these constructs have been available directly off of the main
+  object, so that you could use these at the start of a file without the
+  `RSpec.` prefix. They have also been available off of any class or module so
+  that you can scope your examples within a particular constant namespace.
+
+  RSpec 3 now provides an option to disable this global monkey patching:
+
+  ```ruby
+  config.expose_dsl_globally = false
+  ```
+
+  For backwards compatibility it defaults to `true`.
+
+  Scenario: By default RSpec allows the DSL to be used globally
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "specs here" do
+        it "passes" do
+        end
+      end
+      """
+   When I run `rspec`
+   Then the output should contain "1 example, 0 failures"
+
+  Scenario: When exposing globally is disabled the top level DSL no longer works
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.configure { |c| c.expose_dsl_globally = false }
+      describe "specs here" do
+        it "passes" do
+        end
+      end
+      """
+   When I run `rspec`
+   Then the output should contain "undefined method `describe'"
+
+  Scenario: Regardless of setting
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.configure { |c| c.expose_dsl_globally = true }
+      RSpec.describe "specs here" do
+        it "passes" do
+        end
+      end
+      """
+   When I run `rspec`
+   Then the output should contain "1 example, 0 failures"
diff --git a/rspec-core/features/configuration/exclude_pattern.feature b/rspec-core/features/configuration/exclude_pattern.feature
new file mode 100644
index 0000000..90af092
--- /dev/null
+++ b/rspec-core/features/configuration/exclude_pattern.feature
@@ -0,0 +1,43 @@
+Feature: exclude_pattern
+
+  Use the `--exclude-pattern` option to tell RSpec to skip looking for specs in files
+  that match the pattern specified.
+
+  Background:
+    Given a file named "spec/models/model_spec.rb" with:
+      """ruby
+      RSpec.describe "two specs here" do
+        it "passes" do
+        end
+
+        it "passes too" do
+        end
+      end
+      """
+    And a file named "spec/features/feature_spec.rb" with:
+      """ruby
+      RSpec.describe "only one spec" do
+        it "passes" do
+        end
+      end
+      """
+
+  Scenario: By default, RSpec runs files that match `"**/*_spec.rb"`
+   When I run `rspec`
+   Then the output should contain "3 examples, 0 failures"
+
+  Scenario: The `--exclude-pattern` flag makes RSpec skip matching files
+   When I run `rspec --exclude-pattern "**/models/*_spec.rb"`
+   Then the output should contain "1 example, 0 failures"
+
+  Scenario: The `--exclude-pattern` flag can be used to pass in multiple patterns, separated by comma
+   When I run `rspec --exclude-pattern "**/models/*_spec.rb, **/features/*_spec.rb"`
+   Then the output should contain "0 examples, 0 failures"
+
+  Scenario: The `--exclude-pattern` flag accepts shell style glob unions
+   When I run `rspec --exclude-pattern "**/{models,features}/*_spec.rb"`
+   Then the output should contain "0 examples, 0 failures"
+
+  Scenario: The `--exclude-pattern` flag can be used with the `--pattern` flag
+   When I run `rspec --pattern "spec/**/*_spec.rb" --exclude-pattern "spec/models/*_spec.rb"`
+   Then the output should contain "1 example, 0 failures"
diff --git a/rspec-core/features/configuration/fail_fast.feature b/rspec-core/features/configuration/fail_fast.feature
new file mode 100644
index 0000000..ff11ec9
--- /dev/null
+++ b/rspec-core/features/configuration/fail_fast.feature
@@ -0,0 +1,79 @@
+Feature: fail fast
+
+  Use the `fail_fast` option to tell RSpec to abort the run on first failure:
+
+  ```ruby
+  RSpec.configure { |c| c.fail_fast = true }
+  ```
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure {|c| c.fail_fast = true}
+      """
+
+  Scenario: `fail_fast` with no failures (runs all examples)
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "passes" do
+        end
+
+        it "passes too" do
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `fail_fast` with first example failing (only runs the one example)
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "spec_helper"
+      RSpec.describe "something" do
+        it "fails" do
+          fail
+        end
+
+        it "passes" do
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb -fd`
+    Then the output should contain "1 example, 1 failure"
+
+  Scenario: `fail_fast` with multiple files, second example failing (only runs the first two examples)
+    Given a file named "spec/example_1_spec.rb" with:
+      """ruby
+      require "spec_helper"
+      RSpec.describe "something" do
+        it "passes" do
+        end
+
+        it "fails" do
+          fail
+        end
+      end
+
+      RSpec.describe "something else" do
+        it "fails" do
+          fail
+        end
+      end
+      """
+    And a file named "spec/example_2_spec.rb" with:
+      """ruby
+      require "spec_helper"
+      RSpec.describe "something" do
+        it "passes" do
+        end
+      end
+
+      RSpec.describe "something else" do
+        it "fails" do
+          fail
+        end
+      end
+      """
+    When I run `rspec spec`
+    Then the output should contain "2 examples, 1 failure"
diff --git a/rspec-core/features/configuration/failure_exit_code.feature b/rspec-core/features/configuration/failure_exit_code.feature
new file mode 100644
index 0000000..a61fcdd
--- /dev/null
+++ b/rspec-core/features/configuration/failure_exit_code.feature
@@ -0,0 +1,53 @@
+Feature: failure exit code
+
+  Use the `failure_exit_code` option to set a custom exit code when RSpec fails.
+
+  ```ruby
+  RSpec.configure { |c| c.failure_exit_code = 42 }
+  ```
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure { |c| c.failure_exit_code = 42 }
+      """
+
+  Scenario: A failing spec with the default exit code
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        it "fails" do
+          fail
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the exit status should be 1
+
+  Scenario: A failing spec with a custom exit code
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+      RSpec.describe "something" do
+        it "fails" do
+          fail
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the exit status should be 42
+
+  Scenario: Exit with the default exit code when an `at_exit` hook is added upstream
+    Given a file named "exit_at_spec.rb" with:
+      """ruby
+      require 'rspec/autorun'
+      at_exit { exit(0) }
+
+      RSpec.describe "exit 0 at_exit ignored" do
+        it "does not interfere with the default exit code" do
+          fail
+        end
+      end
+      """
+    When I run `ruby exit_at_spec.rb`
+    Then the exit status should be 1
diff --git a/rspec-core/features/configuration/order_and_seed.feature b/rspec-core/features/configuration/order_and_seed.feature
new file mode 100644
index 0000000..c1efa8e
--- /dev/null
+++ b/rspec-core/features/configuration/order_and_seed.feature
@@ -0,0 +1,5 @@
+Feature: set the order and/or seed
+
+  You can set the order to run specs and specify a seed if you are running the
+  specs using the 'random' ordering. See [the documentation on the `--order`
+  command line option](../command-line/order) for more on this.
diff --git a/rspec-core/features/configuration/output_stream.feature b/rspec-core/features/configuration/output_stream.feature
new file mode 100644
index 0000000..4f1b734
--- /dev/null
+++ b/rspec-core/features/configuration/output_stream.feature
@@ -0,0 +1,27 @@
+Feature: Custom output stream
+
+  Define a custom output stream (default `$stdout`).  Aliases: `:output`,
+  `:out`.
+
+  ```ruby
+  RSpec.configure { |c| c.output_stream = File.open('saved_output', 'w') }
+  ```
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure { |c| c.output_stream = File.open('saved_output', 'w') }
+      """
+
+  Scenario: Redirecting output
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+      RSpec.describe "an example" do
+        it "passes" do
+          true
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the file "saved_output" should contain "1 example, 0 failures"
diff --git a/rspec-core/features/configuration/overriding_global_ordering.feature b/rspec-core/features/configuration/overriding_global_ordering.feature
new file mode 100644
index 0000000..aafb4d2
--- /dev/null
+++ b/rspec-core/features/configuration/overriding_global_ordering.feature
@@ -0,0 +1,90 @@
+Feature: Overriding global ordering
+
+  You can customize how RSpec orders examples and example groups. For an
+  individual group, you can control it by tagging it with `:order` metadata:
+
+    * `:defined` runs the examples (and sub groups) in defined order
+    * `:random` runs them in random order
+
+  If you have more specialized needs, you can register your own ordering using
+  the `register_ordering` configuration option. If you register an ordering as
+  `:global`, it will be the global default, used by all groups that do not have
+  `:order` metadata (and by RSpec to order the top-level groups).
+
+  Scenario: Running a specific example group in order
+    Given a file named "order_dependent_spec.rb" with:
+      """ruby
+      RSpec.describe "examples only pass when they are run in order", :order => :defined do
+        before(:context) { @list = [] }
+
+        it "passes when run first" do
+          @list << 1
+          expect(@list).to eq([1])
+        end
+
+        it "passes when run second" do
+          @list << 2
+          expect(@list).to eq([1, 2])
+        end
+
+        it "passes when run third" do
+          @list << 3
+          expect(@list).to eq([1, 2, 3])
+        end
+      end
+      """
+    When I run `rspec order_dependent_spec.rb --order random:1`
+    Then the examples should all pass
+
+  Scenario: Registering a custom ordering
+    Given a file named "register_custom_ordering_spec.rb" with:
+      """ruby
+      RSpec.configure do |rspec|
+        rspec.register_ordering(:reverse) do |items|
+          items.reverse
+        end
+      end
+
+      RSpec.describe "A group that must run in reverse order", :order => :reverse do
+        before(:context) { @list = [] }
+
+        it "passes when run second" do
+          @list << 2
+          expect(@list).to eq([1, 2])
+        end
+
+        it "passes when run first" do
+          @list << 1
+          expect(@list).to eq([1])
+        end
+      end
+      """
+    When I run `rspec register_custom_ordering_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Using a custom global ordering
+    Given a file named "register_global_ordering_spec.rb" with:
+      """ruby
+      RSpec.configure do |rspec|
+        rspec.register_ordering(:global) do |items|
+          items.reverse
+        end
+      end
+
+      RSpec.describe "A group without :order metadata" do
+        before(:context) { @list = [] }
+
+        it "passes when run second" do
+          @list << 2
+          expect(@list).to eq([1, 2])
+        end
+
+        it "passes when run first" do
+          @list << 1
+          expect(@list).to eq([1])
+        end
+      end
+      """
+    When I run `rspec register_global_ordering_spec.rb`
+    Then the examples should all pass
+
diff --git a/rspec-core/features/configuration/pattern.feature b/rspec-core/features/configuration/pattern.feature
new file mode 100644
index 0000000..7720c4f
--- /dev/null
+++ b/rspec-core/features/configuration/pattern.feature
@@ -0,0 +1,62 @@
+Feature: pattern
+
+  Use the `pattern` option to configure RSpec to look for specs in files that match
+  a pattern instead of the default `"**/*_spec.rb"`.
+
+  ```ruby
+  RSpec.configure { |c| c.pattern = '**/*.spec' }
+  ```
+
+  Rather than using `require 'spec_helper'` at the top of each spec file,
+  ensure that you have `--require spec_helper` in `.rspec`. That will always
+  load before the pattern is resolved. With the pattern thus configured,
+  only those spec files that match the pattern will then be loaded.
+
+  Background:
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "two specs" do
+        it "passes" do
+        end
+
+        it "passes too" do
+        end
+      end
+      """
+
+  Scenario: Override the default pattern in configuration
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.pattern = '**/*.spec'
+      end
+      """
+    And a file named "spec/one_example.spec" with:
+      """ruby
+      RSpec.describe "something" do
+        it "passes" do
+        end
+      end
+      """
+    When I run `rspec -rspec_helper`
+    Then the output should contain "1 example, 0 failures"
+
+  Scenario: Append to the default pattern in configuration
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.pattern << ',**/*.spec'
+      end
+      """
+    And a file named "spec/two_examples.spec" with:
+      """ruby
+      RSpec.describe "something" do
+        it "passes" do
+        end
+
+        it "passes again" do
+        end
+      end
+      """
+    When I run `rspec -rspec_helper`
+    Then the output should contain "4 examples, 0 failures"
diff --git a/rspec-core/features/configuration/profile.feature b/rspec-core/features/configuration/profile.feature
new file mode 100644
index 0000000..402d79d
--- /dev/null
+++ b/rspec-core/features/configuration/profile.feature
@@ -0,0 +1,220 @@
+Feature: Profile examples
+
+  The `--profile` command line option (available from `RSpec.configure` as
+  `#profile_examples`), when set, will cause RSpec to dump out a list of your
+  slowest examples. By default, it prints the 10 slowest examples, but you can
+  set it to a different value to have it print more or fewer slow examples. If
+  `--fail-fast` option is used together with `--profile` and there is a failure,
+  slow examples are not shown.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      """
+    And a file named "spec/example_spec.rb" with:
+      """ruby
+      require "spec_helper"
+
+      RSpec.describe "something" do
+        it "sleeps for 0.1 seconds (example 1)" do
+          sleep 0.1
+          expect(1).to eq(1)
+        end
+
+        it "sleeps for 0 seconds (example 2)" do
+          expect(2).to eq(2)
+        end
+
+        it "sleeps for 0.15 seconds (example 3)" do
+          sleep 0.15
+          expect(3).to eq(3)
+        end
+
+        it "sleeps for 0.05 seconds (example 4)" do
+          sleep 0.05
+          expect(4).to eq(4)
+        end
+
+        it "sleeps for 0.05 seconds (example 5)" do
+          sleep 0.05
+          expect(5).to eq(5)
+        end
+
+        it "sleeps for 0.05 seconds (example 6)" do
+          sleep 0.05
+          expect(6).to eq(6)
+        end
+
+        it "sleeps for 0.05 seconds (example 7)" do
+          sleep 0.05
+          expect(7).to eq(7)
+        end
+
+        it "sleeps for 0.05 seconds (example 8)" do
+          sleep 0.05
+          expect(8).to eq(8)
+        end
+
+        it "sleeps for 0.05 seconds (example 9)" do
+          sleep 0.05
+          expect(9).to eq(9)
+        end
+
+        it "sleeps for 0.05 seconds (example 10)" do
+          sleep 0.05
+          expect(10).to eq(10)
+        end
+
+        it "sleeps for 0.05 seconds (example 11)" do
+          sleep 0.05
+          expect(11).to eq(11)
+        end
+      end
+      """
+
+  Scenario: By default does not show profile
+    When I run `rspec spec`
+    Then the examples should all pass
+    And the output should not contain "example 1"
+    And the output should not contain "example 2"
+    And the output should not contain "example 3"
+    And the output should not contain "example 4"
+    And the output should not contain "example 5"
+    And the output should not contain "example 6"
+    And the output should not contain "example 7"
+    And the output should not contain "example 8"
+    And the output should not contain "example 9"
+    And the output should not contain "example 10"
+    And the output should not contain "example 11"
+
+  Scenario: Setting `profile_examples` to true shows 10 examples
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure { |c| c.profile_examples = true }
+      """
+    When I run `rspec spec`
+    Then the examples should all pass
+    And the output should contain "Top 10 slowest examples"
+    And the output should contain "example 1"
+    And the output should not contain "example 2"
+    And the output should contain "example 3"
+    And the output should contain "example 4"
+    And the output should contain "example 5"
+    And the output should contain "example 6"
+    And the output should contain "example 7"
+    And the output should contain "example 8"
+    And the output should contain "example 9"
+    And the output should contain "example 10"
+    And the output should contain "example 11"
+
+  Scenario: Setting `profile_examples` to 2 shows 2 examples
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure { |c| c.profile_examples = 2 }
+      """
+    When I run `rspec spec`
+    Then the examples should all pass
+    And the output should contain "Top 2 slowest examples"
+    And the output should contain "example 1"
+    And the output should not contain "example 2"
+    And the output should contain "example 3"
+    And the output should not contain "example 4"
+    And the output should not contain "example 5"
+    And the output should not contain "example 6"
+    And the output should not contain "example 7"
+    And the output should not contain "example 8"
+    And the output should not contain "example 9"
+    And the output should not contain "example 10"
+    And the output should not contain "example 11"
+
+  Scenario: Setting profile examples through CLI using `--profile`
+    When I run `rspec spec --profile 2`
+    Then the examples should all pass
+    And the output should contain "Top 2 slowest examples"
+    And the output should contain "example 1"
+    And the output should not contain "example 2"
+    And the output should contain "example 3"
+    And the output should not contain "example 4"
+    And the output should not contain "example 5"
+    And the output should not contain "example 6"
+    And the output should not contain "example 7"
+    And the output should not contain "example 8"
+    And the output should not contain "example 9"
+    And the output should not contain "example 10"
+    And the output should not contain "example 11"
+
+  Scenario: Using `--no-profile` overrules config options
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure { |c| c.profile_examples = true }
+      """
+    When I run `rspec spec --no-profile`
+    Then the examples should all pass
+    And the output should not contain "example 1"
+    And the output should not contain "example 2"
+    And the output should not contain "example 3"
+    And the output should not contain "example 4"
+    And the output should not contain "example 5"
+    And the output should not contain "example 6"
+    And the output should not contain "example 7"
+    And the output should not contain "example 8"
+    And the output should not contain "example 9"
+    And the output should not contain "example 10"
+    And the output should not contain "example 11"
+
+  Scenario: Using `--profile` with `--fail-fast` shows slow examples if everything passes
+    When I run `rspec spec --fail-fast --profile`
+    Then the examples should all pass
+    And the output should contain "Top 10 slowest examples"
+    And the output should contain "example 1"
+    And the output should not contain "example 2"
+    And the output should contain "example 3"
+    And the output should contain "example 4"
+    And the output should contain "example 5"
+    And the output should contain "example 6"
+    And the output should contain "example 7"
+    And the output should contain "example 8"
+    And the output should contain "example 9"
+    And the output should contain "example 10"
+    And the output should contain "example 11"
+
+  Scenario: Using `--profile` shows slow examples even in case of failures
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "spec_helper"
+
+      RSpec.describe "something" do
+        it "sleeps for 0.1 seconds (example 1)" do
+          sleep 0.1
+          expect(1).to eq(1)
+        end
+
+        it "fails" do
+          fail
+        end
+      end
+      """
+    When I run `rspec spec --profile`
+    Then the output should contain "2 examples, 1 failure"
+    And the output should contain "Top 2 slowest examples"
+    And the output should contain "example 1"
+
+  Scenario: Using `--profile` with `--fail-fast` doesn't show slow examples in case of failures
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "spec_helper"
+
+      RSpec.describe "something" do
+        it "sleeps for 0.1 seconds (example 1)" do
+          sleep 0.1
+          expect(1).to eq(1)
+        end
+
+        it "fails" do
+          fail
+        end
+      end
+      """
+    When I run `rspec spec --fail-fast --profile`
+    Then the output should not contain "Top 2 slowest examples"
+    And the output should not contain "example 1"
diff --git a/rspec-core/features/configuration/read_options_from_file.feature b/rspec-core/features/configuration/read_options_from_file.feature
new file mode 100644
index 0000000..d1a11bc
--- /dev/null
+++ b/rspec-core/features/configuration/read_options_from_file.feature
@@ -0,0 +1,95 @@
+Feature: read command line configuration options from files
+
+  RSpec reads command line configuration options from files in three different
+  locations:
+
+    * Local: `./.rspec-local` (i.e. in the project's root directory, can be
+      gitignored)
+
+    * Project:  `./.rspec` (i.e. in the project's root directory, usually
+      checked into the project)
+
+    * Global: `~/.rspec` (i.e. in the user's home directory)
+
+  Configuration options are loaded from `~/.rspec`, `.rspec`, `.rspec-local`,
+  command line switches, and the `SPEC_OPTS` environment variable (listed in
+  lowest to highest precedence; for example, an option in `~/.rspec` can be
+  overridden by an option in `.rspec-local`).
+
+  Scenario: Color set in `.rspec`
+    Given a file named ".rspec" with:
+      """
+      --color
+      """
+    And a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "color_enabled?" do
+        context "when set with RSpec.configure" do
+          before do
+            # color is disabled for non-tty output, so stub the output stream
+            # to say it is tty, even though we're running this with cucumber
+            allow(RSpec.configuration.output_stream).to receive(:tty?) { true }
+          end
+
+          it "is true" do
+            expect(RSpec.configuration).to be_color_enabled
+          end
+        end
+      end
+      """
+    When I run `rspec ./spec/example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Custom options file
+    Given a file named "my.options" with:
+      """
+      --format documentation
+      """
+    And a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "formatter set in custom options file" do
+        it "sets formatter" do
+          expect(RSpec.configuration.formatters.first).
+            to be_a(RSpec::Core::Formatters::DocumentationFormatter)
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb --options my.options`
+    Then the examples should all pass
+
+  Scenario: RSpec ignores `./.rspec` when custom options file is used
+    Given a file named "my.options" with:
+      """
+      --format documentation
+      """
+    And a file named ".rspec" with:
+      """
+      --color
+      """
+    And a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "custom options file" do
+        it "causes .rspec to be ignored" do
+          expect(RSpec.configuration.color).to be_falsey
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb --options my.options`
+    Then the examples should all pass
+
+  Scenario: Using ERB in `.rspec`
+    Given a file named ".rspec" with:
+      """
+      --format <%= true ? 'documentation' : 'progress' %>
+      """
+    And a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "formatter" do
+        it "is set to documentation" do
+          expect(RSpec.configuration.formatters.first).
+            to be_an(RSpec::Core::Formatters::DocumentationFormatter)
+        end
+      end
+      """
+    When I run `rspec ./spec/example_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/configuration/run_all_when_everything_filtered.feature b/rspec-core/features/configuration/run_all_when_everything_filtered.feature
new file mode 100644
index 0000000..92d7bef
--- /dev/null
+++ b/rspec-core/features/configuration/run_all_when_everything_filtered.feature
@@ -0,0 +1,78 @@
+Feature: run all when everything filtered
+
+  Use the `run_all_when_everything_filtered` option to tell RSpec to run all the
+  specs in the case where you try to run a filtered list of specs but no specs
+  match that filter. This works well when paired with an inclusion filter like
+  `:focus => true`, as it will run all the examples when none match the
+  inclusion filter.
+
+  ```ruby
+  RSpec.configure { |c| c.run_all_when_everything_filtered = true }
+  ```
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure {|c| c.run_all_when_everything_filtered = true}
+      """
+
+  Scenario: By default, no specs are run if they are all filtered out by an inclusion tag
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "examples" do
+        it "with no tag" do
+        end
+
+        it "with no tag as well" do
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb --tag some_tag`
+    Then the output should contain "0 examples, 0 failures"
+
+  Scenario: Specs are still run if they are filtered out by an exclusion tag
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "examples" do
+        it "with no tag" do
+        end
+
+        it "with no tag as well" do
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb --tag ~some_tag`
+    Then the output should contain "2 examples, 0 failures"
+
+  Scenario: When the `run_all_when_everything_filtered` option is turned on, if there are any matches for the filtering tag, only those features are run
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "spec_helper"
+      RSpec.describe "examples" do
+        it "with no tag", :some_tag => true do
+        end
+
+        it "with no tag as well" do
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb --tag some_tag`
+    Then the output should contain "1 example, 0 failures"
+    And the output should contain "Run options: include {:some_tag=>true}"
+
+  Scenario: When the `run_all_when_everything_filtered` option is turned on, all the specs are run when the tag has no matches
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "spec_helper"
+      RSpec.describe "examples" do
+        it "with no tag" do
+        end
+
+        it "with no tag as well" do
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb --tag some_tag`
+    Then the output should contain "2 examples, 0 failures"
+    And the output should contain "All examples were filtered out; ignoring {:some_tag=>true}"
+
diff --git a/rspec-core/features/configuration/zero_monkey_patching_mode.feature b/rspec-core/features/configuration/zero_monkey_patching_mode.feature
new file mode 100644
index 0000000..f38356b
--- /dev/null
+++ b/rspec-core/features/configuration/zero_monkey_patching_mode.feature
@@ -0,0 +1,106 @@
+ at allow-should-syntax
+Feature: Zero monkey patching mode
+
+  Use the `disable_monkey_patching!` configuration option to
+  disable all monkey patching done by RSpec:
+
+  - stops exposing DSL globally
+  - disables `should` and `should_not` syntax for rspec-expectations
+  - disables `stub`, `should_receive`, and `should_not_receive` syntax for
+    rspec-mocks
+
+  ```ruby
+  RSpec.configure { |c| c.disable_monkey_patching! }
+  ```
+
+  Background:
+    Given a file named "spec/example_describe_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+
+      describe "specs here" do
+        it "passes" do
+        end
+      end
+      """
+    Given a file named "spec/example_should_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+
+      RSpec.describe "another specs here" do
+        it "passes with monkey patched expectations" do
+          x = 25
+          x.should eq 25
+          x.should_not be > 30
+        end
+
+        it "passes with monkey patched mocks" do
+          x = double("thing")
+          x.stub(:hello => [:world])
+          x.should_receive(:count).and_return(4)
+          x.should_not_receive(:all)
+          (x.hello * x.count).should eq([:world, :world, :world, :world])
+        end
+      end
+      """
+    Given a file named "spec/example_expect_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+
+      RSpec.describe "specs here too" do
+        it "passes in zero monkey patching mode" do
+          x = double("thing")
+          allow(x).to receive(:hello).and_return([:world])
+          expect(x).to receive(:count).and_return(4)
+          expect(x).not_to receive(:all)
+          expect(x.hello * x.count).to eq([:world, :world, :world, :world])
+        end
+
+        it "passes in zero monkey patching mode" do
+          x = 25
+          expect(x).to eq(25)
+          expect(x).not_to be > 30
+        end
+      end
+      """
+
+  Scenario: By default RSpec allows monkey patching
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      # Empty spec_helper
+      """
+    When I run `rspec`
+    Then the examples should all pass
+
+  Scenario: Monkey patched methods are undefined with `disable_monkey_patching!`
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.disable_monkey_patching!
+      end
+      """
+    When I run `rspec spec/example_should_spec.rb`
+    Then the output should contain all of these:
+      | undefined method `should'   |
+      | unexpected message :stub    |
+    When I run `rspec spec/example_describe_spec.rb`
+    Then the output should contain "undefined method `describe'"
+
+  Scenario: `allow` and `expect` syntax works with monkey patching
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      # Empty spec_helper
+      """
+    When I run `rspec spec/example_expect_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `allow` and `expect` syntax works without monkey patching
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.disable_monkey_patching!
+      end
+      """
+    When I run `rspec spec/example_expect_spec.rb`
+    Then the examples should all pass
+
diff --git a/rspec-core/features/core_standalone.feature b/rspec-core/features/core_standalone.feature
new file mode 100644
index 0000000..a583563
--- /dev/null
+++ b/rspec-core/features/core_standalone.feature
@@ -0,0 +1,23 @@
+Feature: Use rspec-core without rspec-mocks or rspec-expectations
+
+  It is most common to use rspec-core with rspec-mocks and rspec-expectations,
+  and rspec-core will take care of loading those libraries automatically if
+  available, but rspec-core can be used just fine without either of those
+  gems installed.
+
+  Scenario: Use only rspec-core when only it is installed
+    Given only rspec-core is installed
+      And a file named "core_only_spec.rb" with:
+        """ruby
+        RSpec.describe "Only rspec-core is available" do
+          it "it fails when an rspec-mocks API is used" do
+            dbl = double("MyDouble")
+          end
+
+          it "it fails when an rspec-expectations API is used" do
+            expect(1).to eq(1)
+          end
+        end
+        """
+    When I run `rspec core_only_spec.rb`
+    Then the output should contain "2 examples, 2 failures"
diff --git a/rspec-core/features/example_groups/aliasing.feature b/rspec-core/features/example_groups/aliasing.feature
new file mode 100644
index 0000000..da5d1a6
--- /dev/null
+++ b/rspec-core/features/example_groups/aliasing.feature
@@ -0,0 +1,48 @@
+Feature: aliasing
+
+  `describe` and `context` are the default aliases for `example_group`. You can
+  define your own aliases for `example_group` and give those custom aliases
+  default metadata.
+
+  RSpec provides a few built-in aliases:
+
+    * `xdescribe` and `xcontext` add `:skip` metadata to the example group in
+      order to temporarily disable the examples.
+    * `fdescribe` and `fcontext` add `:focus` metadata to the example group in
+      order to make it easy to temporarily focus the example group (when
+      combined with `config.filter_run :focus`.)
+
+  Scenario: Custom example group aliases with metadata
+    Given a file named "nested_example_group_aliases_spec.rb" with:
+    """ruby
+    RSpec.configure do |c|
+      c.alias_example_group_to :detail, :detailed => true
+    end
+
+    RSpec.detail "a detail" do
+      it "can do some less important stuff" do
+      end
+    end
+
+    RSpec.describe "a thing" do
+      describe "in broad strokes" do
+        it "can do things" do
+        end
+      end
+
+      detail "something less important" do
+        it "can do an unimportant thing" do
+        end
+      end
+    end
+    """
+    When I run `rspec nested_example_group_aliases_spec.rb --tag detailed -fdoc`
+    Then the output should contain:
+      """
+      a detail
+        can do some less important stuff
+
+      a thing
+        something less important
+      """
+
diff --git a/rspec-core/features/example_groups/basic_structure.feature b/rspec-core/features/example_groups/basic_structure.feature
new file mode 100644
index 0000000..eb284df
--- /dev/null
+++ b/rspec-core/features/example_groups/basic_structure.feature
@@ -0,0 +1,55 @@
+Feature: basic structure (`describe`/`it`)
+
+  RSpec is a DSL for creating executable examples of how code is expected to
+  behave, organized in groups. It uses the words "describe" and "it" so we can
+  express concepts like a conversation:
+
+      "Describe an account when it is first opened."
+      "It has a balance of zero."
+
+  The `describe` method creates an example group.  Within the block passed to
+  `describe` you can declare nested groups using the `describe` or `context`
+  methods, or you can declare examples using the `it` or `specify` methods.
+
+  Under the hood, an example group is a class in which the block passed to
+  `describe` or `context` is evaluated. The blocks passed to `it` are evaluated
+  in the context of an _instance_ of that class.
+
+  Scenario: One group, one example
+    Given a file named "sample_spec.rb" with:
+    """ruby
+    RSpec.describe "something" do
+      it "does something" do
+      end
+    end
+    """
+    When I run `rspec sample_spec.rb -fdoc`
+    Then the output should contain:
+      """
+      something
+        does something
+      """
+
+  Scenario: Nested example groups (using `context`)
+    Given a file named "nested_example_groups_spec.rb" with:
+    """ruby
+    RSpec.describe "something" do
+      context "in one context" do
+        it "does one thing" do
+        end
+      end
+      context "in another context" do
+        it "does another thing" do
+        end
+      end
+    end
+    """
+    When I run `rspec nested_example_groups_spec.rb -fdoc`
+    Then the output should contain:
+      """
+      something
+        in one context
+          does one thing
+        in another context
+          does another thing
+      """
diff --git a/rspec-core/features/example_groups/shared_context.feature b/rspec-core/features/example_groups/shared_context.feature
new file mode 100644
index 0000000..c21e238
--- /dev/null
+++ b/rspec-core/features/example_groups/shared_context.feature
@@ -0,0 +1,112 @@
+Feature: shared context
+
+  Use `shared_context` to define a block that will be evaluated in the context
+  of example groups either explicitly, using `include_context`, or implicitly by
+  matching metadata.
+
+  When implicitly including shared contexts via matching metadata, the normal way is to define matching metadata on an example group (in which case the ontext is included in the entire group), but you can also include it in an individual example. RSpec treats every example as having a singleton example group (analogous to Ruby's singleton classes) containing just the one example.
+
+  Background:
+    Given a file named "shared_stuff.rb" with:
+      """ruby
+      RSpec.shared_context "shared stuff", :a => :b do
+        before { @some_var = :some_value }
+        def shared_method
+          "it works"
+        end
+        let(:shared_let) { {'arbitrary' => 'object'} }
+        subject do
+          'this is the subject'
+        end
+      end
+      """
+
+  Scenario: Declare a shared context and include it with `include_context`
+    Given a file named "shared_context_example.rb" with:
+      """ruby
+      require "./shared_stuff.rb"
+
+      RSpec.describe "group that includes a shared context using 'include_context'" do
+        include_context "shared stuff"
+
+        it "has access to methods defined in shared context" do
+          expect(shared_method).to eq("it works")
+        end
+
+        it "has access to methods defined with let in shared context" do
+          expect(shared_let['arbitrary']).to eq('object')
+        end
+
+        it "runs the before hooks defined in the shared context" do
+          expect(@some_var).to be(:some_value)
+        end
+
+        it "accesses the subject defined in the shared context" do
+          expect(subject).to eq('this is the subject')
+        end
+      end
+      """
+    When I run `rspec shared_context_example.rb`
+    Then the examples should all pass
+
+  Scenario: Declare a shared context, include it with `include_context` and extend it with an additional block
+    Given a file named "shared_context_example.rb" with:
+      """ruby
+      require "./shared_stuff.rb"
+
+      RSpec.describe "including shared context using 'include_context' and a block" do
+        include_context "shared stuff" do
+          let(:shared_let) { {'in_a' => 'block'} }
+        end
+
+        it "evaluates the block in the shared context" do
+          expect(shared_let['in_a']).to eq('block')
+        end
+      end
+      """
+    When I run `rspec shared_context_example.rb`
+    Then the examples should all pass
+
+  Scenario: Declare a shared context and include it with metadata
+    Given a file named "shared_context_example.rb" with:
+      """ruby
+      require "./shared_stuff.rb"
+
+      RSpec.describe "group that includes a shared context using metadata", :a => :b do
+        it "has access to methods defined in shared context" do
+          expect(shared_method).to eq("it works")
+        end
+
+        it "has access to methods defined with let in shared context" do
+          expect(shared_let['arbitrary']).to eq('object')
+        end
+
+        it "runs the before hooks defined in the shared context" do
+          expect(@some_var).to be(:some_value)
+        end
+
+        it "accesses the subject defined in the shared context" do
+          expect(subject).to eq('this is the subject')
+        end
+      end
+      """
+    When I run `rspec shared_context_example.rb`
+    Then the examples should all pass
+
+  Scenario: Declare a shared context and include it with metadata of an individual example
+    Given a file named "shared_context_example.rb" with:
+      """ruby
+      require "./shared_stuff.rb"
+
+      RSpec.describe "group that does not include the shared context" do
+        it "does not have access to shared methods normally" do
+          expect(self).not_to respond_to(:shared_method)
+        end
+
+        it "has access to shared methods from examples with matching metadata", :a => :b do
+          expect(shared_method).to eq("it works")
+        end
+      end
+      """
+    When I run `rspec shared_context_example.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/example_groups/shared_examples.feature b/rspec-core/features/example_groups/shared_examples.feature
new file mode 100644
index 0000000..27563be
--- /dev/null
+++ b/rspec-core/features/example_groups/shared_examples.feature
@@ -0,0 +1,295 @@
+Feature: shared examples
+
+  Shared examples let you describe behaviour of classes or modules. When declared,
+  a shared group's content is stored. It is only realized in the context of
+  another example group, which provides any context the shared group needs to
+  run.
+
+  A shared group is included in another group using any of:
+
+  ```ruby
+  include_examples "name"      # include the examples in the current context
+  it_behaves_like "name"       # include the examples in a nested context
+  it_should_behave_like "name" # include the examples in a nested context
+  matching metadata            # include the examples in the current context
+  ```
+
+  **WARNING:** Files containing shared groups must be loaded before the files that
+  use them.  While there are conventions to handle this, RSpec does _not_ do
+  anything special (like autoload). Doing so would require a strict naming
+  convention for files that would break existing suites.
+
+  Conventions:
+  ------------
+
+  1.  The simplest approach is to require files with shared examples explicitly
+      from the files that use them. Keep in mind that RSpec adds the `spec`
+      directory to the `LOAD_PATH`, so you can say `require
+      'shared_examples_for_widgets'` to require a file at
+      `#{PROJECT_ROOT}/spec/shared_examples_for_widgets.rb`.
+
+  2.  One convention is to put files containing shared examples in `spec/support/`
+      and require files in that directory from `spec/spec_helper.rb`:
+
+      ```ruby
+      Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
+      ```
+
+      Historically, this was included in the generated `spec/spec_helper.rb` file in
+      `rspec-rails`. However, in order to keep your test suite boot time down,
+      it's a good idea to not autorequire all files in a directory like this.
+      When running only one spec file, loading unneeded dependencies or performing
+      unneeded setup can have a significant, noticable effect on how long it takes
+      before the first example runs.
+
+  3. When all of the groups that include the shared group reside in the same file,
+     just declare the shared group in that file.
+
+  Scenario: Shared examples group included in two groups in one file
+    Given a file named "collection_spec.rb" with:
+      """ruby
+      require "set"
+
+      RSpec.shared_examples "a collection" do
+        let(:collection) { described_class.new([7, 2, 4]) }
+
+        context "initialized with 3 items" do
+          it "says it has three items" do
+            expect(collection.size).to eq(3)
+          end
+        end
+
+        describe "#include?" do
+          context "with an an item that is in the collection" do
+            it "returns true" do
+              expect(collection.include?(7)).to be_truthy
+            end
+          end
+
+          context "with an an item that is not in the collection" do
+            it "returns false" do
+              expect(collection.include?(9)).to be_falsey
+            end
+          end
+        end
+      end
+
+      RSpec.describe Array do
+        it_behaves_like "a collection"
+      end
+
+      RSpec.describe Set do
+        it_behaves_like "a collection"
+      end
+      """
+    When I run `rspec collection_spec.rb --format documentation`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      Array
+        behaves like a collection
+          initialized with 3 items
+            says it has three items
+          #include?
+            with an an item that is in the collection
+              returns true
+            with an an item that is not in the collection
+              returns false
+
+      Set
+        behaves like a collection
+          initialized with 3 items
+            says it has three items
+          #include?
+            with an an item that is in the collection
+              returns true
+            with an an item that is not in the collection
+              returns false
+      """
+
+  Scenario: Providing context to a shared group using a block
+    Given a file named "shared_example_group_spec.rb" with:
+    """ruby
+    require "set"
+
+    RSpec.shared_examples "a collection object" do
+      describe "<<" do
+        it "adds objects to the end of the collection" do
+          collection << 1
+          collection << 2
+          expect(collection.to_a).to match_array([1, 2])
+        end
+      end
+    end
+
+    RSpec.describe Array do
+      it_behaves_like "a collection object" do
+        let(:collection) { Array.new }
+      end
+    end
+
+    RSpec.describe Set do
+      it_behaves_like "a collection object" do
+        let(:collection) { Set.new }
+      end
+    end
+    """
+    When I run `rspec shared_example_group_spec.rb --format documentation`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      Array
+        behaves like a collection object
+          <<
+            adds objects to the end of the collection
+
+      Set
+        behaves like a collection object
+          <<
+            adds objects to the end of the collection
+      """
+
+  Scenario: Passing parameters to a shared example group
+    Given a file named "shared_example_group_params_spec.rb" with:
+    """ruby
+    RSpec.shared_examples "a measurable object" do |measurement, measurement_methods|
+      measurement_methods.each do |measurement_method|
+        it "should return #{measurement} from ##{measurement_method}" do
+          expect(subject.send(measurement_method)).to eq(measurement)
+        end
+      end
+    end
+
+    RSpec.describe Array, "with 3 items" do
+      subject { [1, 2, 3] }
+      it_should_behave_like "a measurable object", 3, [:size, :length]
+    end
+
+    RSpec.describe String, "of 6 characters" do
+      subject { "FooBar" }
+      it_should_behave_like "a measurable object", 6, [:size, :length]
+    end
+    """
+    When I run `rspec shared_example_group_params_spec.rb --format documentation`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      Array with 3 items
+        it should behave like a measurable object
+          should return 3 from #size
+          should return 3 from #length
+
+      String of 6 characters
+        it should behave like a measurable object
+          should return 6 from #size
+          should return 6 from #length
+      """
+
+  Scenario: Aliasing `it_should_behave_like` to `it_has_behavior`
+    Given a file named "shared_example_group_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:'
+      end
+
+      RSpec.shared_examples 'sortability' do
+        it 'responds to <=>' do
+          expect(sortable).to respond_to(:<=>)
+        end
+      end
+
+      RSpec.describe String do
+        it_has_behavior 'sortability' do
+          let(:sortable) { 'sample string' }
+        end
+      end
+      """
+    When I run `rspec shared_example_group_spec.rb --format documentation`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      String
+        has behavior: sortability
+          responds to <=>
+      """
+
+  Scenario: Sharing metadata automatically includes shared example groups
+    Given a file named "shared_example_metadata_spec.rb" with:
+      """ruby
+      RSpec.shared_examples "shared stuff", :a => :b do
+        it 'runs wherever the metadata is shared' do
+        end
+      end
+
+      RSpec.describe String, :a => :b do
+      end
+      """
+    When I run `rspec shared_example_metadata_spec.rb`
+    Then the output should contain:
+      """
+      1 example, 0 failures
+      """
+
+  Scenario: Shared examples are nestable by context
+    Given a file named "context_specific_examples_spec.rb" with:
+      """Ruby
+      RSpec.describe "shared examples" do
+        context "per context" do
+
+          shared_examples "shared examples are nestable" do
+            specify { expect(true).to eq true }
+          end
+
+          it_behaves_like "shared examples are nestable"
+        end
+      end
+      """
+    When I run `rspec context_specific_examples_spec.rb`
+    Then the output should contain:
+      """
+      1 example, 0 failures
+      """
+
+  Scenario: Shared examples are accessible from offspring contexts
+    Given a file named "context_specific_examples_spec.rb" with:
+      """Ruby
+      RSpec.describe "shared examples" do
+        shared_examples "shared examples are nestable" do
+          specify { expect(true).to eq true }
+        end
+
+        context "per context" do
+          it_behaves_like "shared examples are nestable"
+        end
+      end
+      """
+    When I run `rspec context_specific_examples_spec.rb`
+    Then the output should contain:
+      """
+      1 example, 0 failures
+      """
+    And the output should not contain:
+      """
+      Accessing shared_examples defined across contexts is deprecated
+      """
+
+  Scenario: Shared examples are isolated per context
+    Given a file named "isolated_shared_examples_spec.rb" with:
+      """Ruby
+      RSpec.describe "shared examples" do
+        context do
+          shared_examples "shared examples are isolated" do
+            specify { expect(true).to eq true }
+          end
+        end
+
+        context do
+          it_behaves_like "shared examples are isolated"
+        end
+      end
+      """
+    When I run `rspec isolated_shared_examples_spec.rb`
+    Then the output should contain:
+      """
+      Could not find shared examples \"shared examples are isolated\"
+      """
diff --git a/rspec-core/features/expectation_framework_integration/configure_expectation_framework.feature b/rspec-core/features/expectation_framework_integration/configure_expectation_framework.feature
new file mode 100644
index 0000000..6a28436
--- /dev/null
+++ b/rspec-core/features/expectation_framework_integration/configure_expectation_framework.feature
@@ -0,0 +1,171 @@
+Feature: configure expectation framework
+
+  By default, RSpec is configured to include rspec-expectations for expressing
+  desired outcomes. You can also configure RSpec to use:
+
+  * rspec/expectations (explicitly)
+  * test/unit assertions
+  * minitest assertions
+  * any combination of the above libraries
+
+  Note that when you do not use rspec-expectations, you must explicitly provide
+  a description to every example. You cannot rely on the generated descriptions
+  provided by rspec-expectations.
+
+  Scenario: Default configuration uses rspec-expectations
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :be_a_multiple_of do |factor|
+        match do |actual|
+          actual % factor == 0
+        end
+      end
+
+      RSpec.describe 6 do
+        it { is_expected.to be_a_multiple_of 3 }
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Configure rspec-expectations (explicitly)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :rspec
+      end
+
+      RSpec.describe 5 do
+        it "is greater than 4" do
+          expect(5).to be > 4
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Configure test/unit assertions
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :test_unit
+      end
+
+      RSpec.describe [1] do
+        it "is equal to [1]" do
+          assert_equal [1], [1], "expected [1] to equal [1]"
+        end
+
+        specify { assert_not_equal [1], [] }
+
+        it "is equal to [2] (intentional failure)" do
+          assert [1] == [2], "errantly expected [2] to equal [1]"
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should match:
+      """
+           (Test::Unit::AssertionFailedError|Mini(T|t)est::Assertion):
+             errantly expected \[2\] to equal \[1\]
+      """
+    And  the output should contain "3 examples, 1 failure"
+
+  Scenario: Configure minitest assertions
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :minitest
+      end
+
+      RSpec.describe "Object identity" do
+        it "the an object is the same as itself" do
+          x = [1]
+          assert_same x, x, "expected x to be the same x"
+        end
+
+        specify { refute_same [1], [1] }
+
+        it "is empty (intentional failure)" do
+          assert_empty [1], "errantly expected [1] to be empty"
+        end
+
+        it "marks pending for skip method" do
+          skip "intentionally"
+        end
+      end
+      """
+    When I run `rspec -b example_spec.rb`
+    Then the output should match:
+      """
+           MiniT|test::Assertion:
+             errantly expected \[1\] to be empty
+      """
+    And  the output should contain "4 examples, 1 failure, 1 pending"
+    And  the output should not contain "Warning: you should require 'minitest/autorun' instead."
+
+  Scenario: Configure rspec/expectations AND test/unit assertions
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :rspec, :test_unit
+      end
+
+      RSpec.describe [1] do
+        it "is equal to [1]" do
+          assert_equal [1], [1], "expected [1] to equal [1]"
+        end
+
+        it "matches array [1]" do
+          is_expected.to match_array([1])
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Configure rspec/expectations AND minitest assertions
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :rspec, :minitest
+      end
+
+      RSpec.describe "Object identity" do
+        it "two arrays are not the same object" do
+          refute_same [1], [1]
+        end
+
+        it "an array is itself" do
+          array = [1]
+          expect(array).to be array
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Configure test/unit and minitest assertions
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :test_unit, :minitest
+      end
+
+      RSpec.describe [1] do
+        it "is equal to [1]" do
+          assert_equal [1], [1], "expected [1] to equal [1]"
+        end
+
+        specify { assert_not_equal [1], [] }
+
+        it "the an object is the same as itself" do
+          x = [1]
+          assert_same x, x, "expected x to be the same x"
+        end
+
+        specify { refute_same [1], [1] }
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/filtering/exclusion_filters.feature b/rspec-core/features/filtering/exclusion_filters.feature
new file mode 100644
index 0000000..4cf4813
--- /dev/null
+++ b/rspec-core/features/filtering/exclusion_filters.feature
@@ -0,0 +1,135 @@
+Feature: exclusion filters
+
+  You can exclude examples from a run by declaring an exclusion filter and then
+  tagging examples, or entire groups, with that filter. You can also specify
+  metadata using only symbols.
+
+  Scenario: Exclude an example
+    Given a file named "spec/sample_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        # declare an exclusion filter
+        c.filter_run_excluding :broken => true
+      end
+
+      RSpec.describe "something" do
+        it "does one thing" do
+        end
+
+        # tag example for exclusion by adding metadata
+        it "does another thing", :broken => true do
+        end
+      end
+      """
+    When I run `rspec ./spec/sample_spec.rb --format doc`
+    Then the output should contain "does one thing"
+    And the output should not contain "does another thing"
+
+  Scenario: Exclude a group
+    Given a file named "spec/sample_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run_excluding :broken => true
+      end
+
+      RSpec.describe "group 1", :broken => true do
+        it "group 1 example 1" do
+        end
+
+        it "group 1 example 2" do
+        end
+      end
+
+      RSpec.describe "group 2" do
+        it "group 2 example 1" do
+        end
+      end
+      """
+    When I run `rspec ./spec/sample_spec.rb --format doc`
+    Then the output should contain "group 2 example 1"
+    And  the output should not contain "group 1 example 1"
+    And  the output should not contain "group 1 example 2"
+
+  Scenario: Exclude multiple groups
+    Given a file named "spec/sample_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run_excluding :broken => true
+      end
+
+      RSpec.describe "group 1", :broken => true do
+        before(:context) do
+          raise "you should not see me"
+        end
+
+        it "group 1 example 1" do
+        end
+
+        it "group 1 example 2" do
+        end
+      end
+
+      RSpec.describe "group 2", :broken => true do
+        before(:example) do
+          raise "you should not see me"
+        end
+
+        it "group 2 example 1" do
+        end
+      end
+      """
+    When I run `rspec ./spec/sample_spec.rb --format doc`
+    Then the process should succeed even though no examples were run
+    And  the output should not contain "group 1"
+    And  the output should not contain "group 2"
+
+  Scenario: `before`/`after(:context)` hooks in excluded example group are not run
+    Given a file named "spec/before_after_context_exclusion_filter_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run_excluding :broken => true
+      end
+
+      RSpec.describe "group 1" do
+        before(:context) { puts "before context in included group" }
+        after(:context)  { puts "after context in included group"  }
+
+        it "group 1 example" do
+        end
+      end
+
+      RSpec.describe "group 2", :broken => true do
+        before(:context) { puts "before context in excluded group" }
+        after(:context)  { puts "after context in excluded group"  }
+
+        context "context 1" do
+          it "group 2 context 1 example 1" do
+          end
+        end
+      end
+      """
+    When I run `rspec ./spec/before_after_context_exclusion_filter_spec.rb`
+    Then the output should contain "before context in included group"
+     And the output should contain "after context in included group"
+     And the output should not contain "before context in excluded group"
+     And the output should not contain "after context in excluded group"
+
+  Scenario: Use symbols as metadata
+    Given a file named "symbols_as_metadata_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run_excluding :broken
+      end
+
+      RSpec.describe "something" do
+        it "does one thing" do
+        end
+
+        # tag example for exclusion by adding metadata
+        it "does another thing", :broken do
+        end
+      end
+      """
+    When I run `rspec symbols_as_metadata_spec.rb --format doc`
+    Then the output should contain "does one thing"
+    And the output should not contain "does another thing"
diff --git a/rspec-core/features/filtering/if_and_unless.feature b/rspec-core/features/filtering/if_and_unless.feature
new file mode 100644
index 0000000..44caa67
--- /dev/null
+++ b/rspec-core/features/filtering/if_and_unless.feature
@@ -0,0 +1,165 @@
+Feature: Conditional Filters
+
+  The `:if` and `:unless` metadata keys can be used to filter examples without
+  needing to configure an exclusion filter.
+
+  Scenario: Implicit `:if` filter
+    Given a file named "implicit_if_filter_spec.rb" with:
+      """ruby
+      RSpec.describe ":if => true group", :if => true do
+        it(":if => true group :if => true example", :if => true) { }
+        it(":if => true group :if => false example", :if => false) { }
+        it(":if => true group no :if example") { }
+      end
+
+      RSpec.describe ":if => false group", :if => false do
+        it(":if => false group :if => true example", :if => true) { }
+        it(":if => false group :if => false example", :if => false) { }
+        it(":if => false group no :if example") { }
+      end
+
+      RSpec.describe "no :if group" do
+        it("no :if group :if => true example", :if => true) { }
+        it("no :if group :if => false example", :if => false) { }
+        it("no :if group no :if example") { }
+      end
+      """
+    When I run `rspec implicit_if_filter_spec.rb --format doc`
+    Then the output should contain all of these:
+      | :if => true group :if => true example  |
+      | :if => true group no :if example       |
+      | :if => false group :if => true example |
+      | no :if group :if => true example       |
+      | no :if group no :if example            |
+    And the output should not contain any of these:
+      | :if => true group :if => false example  |
+      | :if => false group :if => false example |
+      | :if => false group no :if example       |
+      | no :if group :if => false example       |
+
+  Scenario: Implicit `:unless` filter
+    Given a file named "implicit_unless_filter_spec.rb" with:
+      """ruby
+      RSpec.describe ":unless => true group", :unless => true do
+        it(":unless => true group :unless => true example", :unless => true) { }
+        it(":unless => true group :unless => false example", :unless => false) { }
+        it(":unless => true group no :unless example") { }
+      end
+
+      RSpec.describe ":unless => false group", :unless => false do
+        it(":unless => false group :unless => true example", :unless => true) { }
+        it(":unless => false group :unless => false example", :unless => false) { }
+        it(":unless => false group no :unless example") { }
+      end
+
+      RSpec.describe "no :unless group" do
+        it("no :unless group :unless => true example", :unless => true) { }
+        it("no :unless group :unless => false example", :unless => false) { }
+        it("no :unless group no :unless example") { }
+      end
+      """
+    When I run `rspec implicit_unless_filter_spec.rb --format doc`
+    Then the output should contain all of these:
+      | :unless => true group :unless => false example  |
+      | :unless => false group :unless => false example |
+      | :unless => false group no :unless example       |
+      | no :unless group :unless => false example       |
+      | no :unless group no :unless example             |
+    And the output should not contain any of these:
+      | :unless => true group :unless => true example  |
+      | :unless => true group no :unless example       |
+      | :unless => false group :unless => true example |
+      | no :unless group :unless => true example       |
+
+  Scenario: Combining implicit filter with explicit inclusion filter
+    Given a file named "explicit_inclusion_filter_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run :focus => true
+      end
+
+      RSpec.describe "group with :focus", :focus => true do
+        it("focused example") { }
+        it("focused :if => true example", :if => true) { }
+        it("focused :if => false example", :if => false) { }
+        it("focused :unless => true example", :unless => true) { }
+        it("focused :unless => false example", :unless => false) { }
+      end
+
+      RSpec.describe "group without :focus" do
+        it("unfocused example") { }
+        it("unfocused :if => true example", :if => true) { }
+        it("unfocused :if => false example", :if => false) { }
+        it("unfocused :unless => true example", :unless => true) { }
+        it("unfocused :unless => false example", :unless => false) { }
+      end
+      """
+    When I run `rspec explicit_inclusion_filter_spec.rb --format doc`
+    Then the output should contain all of these:
+      | focused example                  |
+      | focused :if => true example      |
+      | focused :unless => false example |
+    And the output should not contain any of these:
+      | focused :if => false example     |
+      | focused :unless => true example  |
+      | unfocused                        |
+
+  Scenario: Combining implicit filter with explicit exclusion filter
+    Given a file named "explicit_exclusion_filter_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run_excluding :broken => true
+      end
+
+      RSpec.describe "unbroken group" do
+        it("included example") { }
+        it("included :if => true example", :if => true) { }
+        it("included :if => false example", :if => false) { }
+        it("included :unless => true example", :unless => true) { }
+        it("included :unless => false example", :unless => false) { }
+      end
+
+      RSpec.describe "broken group", :broken => true do
+        it("excluded example") { }
+        it("excluded :if => true example", :if => true) { }
+        it("excluded :if => false example", :if => false) { }
+        it("excluded :unless => true example", :unless => true) { }
+        it("excluded :unless => false example", :unless => false) { }
+      end
+      """
+    When I run `rspec explicit_exclusion_filter_spec.rb --format doc`
+    Then the output should contain all of these:
+      | included example                  |
+      | included :if => true example      |
+      | included :unless => false example |
+    And the output should not contain any of these:
+      | included :if => false example     |
+      | included :unless => true example  |
+      | excluded                          |
+
+  Scenario: The :if and :unless exclusions stay in effect when there are explicit inclusions
+    Given a file named "if_and_unless_spec.rb" with:
+      """ruby
+      RSpec.describe "Using inclusions" do
+        context "inclusion target" do
+          it "is filtered out by :if", :if => false do
+          end
+
+          it 'is filtered out by :unless', :unless => true do
+          end
+
+          it 'is still run according to :if', :if => true do
+          end
+
+          it 'is still run according to :unless', :unless => false do
+          end
+        end
+      end
+      """
+    When I run `rspec if_and_unless_spec.rb --format doc -e 'inclusion target'`
+    Then the output should contain all of these:
+      | is still run according to :if     |
+      | is still run according to :unless |
+    And the output should not contain any of these:
+      | is filtered out by :if         |
+      | is filtered out by :unless     |
diff --git a/rspec-core/features/filtering/inclusion_filters.feature b/rspec-core/features/filtering/inclusion_filters.feature
new file mode 100644
index 0000000..8882924
--- /dev/null
+++ b/rspec-core/features/filtering/inclusion_filters.feature
@@ -0,0 +1,101 @@
+Feature: inclusion filters
+
+  You can constrain which examples are run by declaring an inclusion filter.
+  The most common use case is to focus on a subset of examples as you're focused
+  on a particular problem. You can also specify metadata using only symbols.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run_including :focus => true
+      end
+      """
+
+  Scenario: Focus on an example
+    Given a file named "spec/sample_spec.rb" with:
+      """ruby
+      require "spec_helper"
+
+      RSpec.describe "something" do
+        it "does one thing" do
+        end
+
+        it "does another thing", :focus => true do
+        end
+      end
+      """
+    When I run `rspec spec/sample_spec.rb --format doc`
+    Then the output should contain "does another thing"
+    And the output should not contain "does one thing"
+
+  Scenario: Focus on a group
+    Given a file named "spec/sample_spec.rb" with:
+      """ruby
+      require "spec_helper"
+
+      RSpec.describe "group 1", :focus => true do
+        it "group 1 example 1" do
+        end
+
+        it "group 1 example 2" do
+        end
+      end
+
+      RSpec.describe "group 2" do
+        it "group 2 example 1" do
+        end
+      end
+      """
+    When I run `rspec spec/sample_spec.rb --format doc`
+    Then the output should contain "group 1 example 1"
+    And  the output should contain "group 1 example 2"
+    And  the output should not contain "group 2 example 1"
+
+  Scenario: `before`/`after(:context)` hooks in unmatched example group are not run
+    Given a file named "spec/before_after_all_inclusion_filter_spec.rb" with:
+      """ruby
+      require "spec_helper"
+
+      RSpec.describe "group 1", :focus => true do
+        before(:context) { puts "before all in focused group" }
+        after(:context)  { puts "after all in focused group"  }
+
+        it "group 1 example" do
+        end
+      end
+
+      RSpec.describe "group 2" do
+        before(:context) { puts "before all in unfocused group" }
+        after(:context)  { puts "after all in unfocused group"  }
+
+        context "context 1" do
+          it "group 2 context 1 example 1" do
+          end
+        end
+      end
+      """
+    When I run `rspec ./spec/before_after_all_inclusion_filter_spec.rb`
+    Then the output should contain "before all in focused group"
+     And the output should contain "after all in focused group"
+     And the output should not contain "before all in unfocused group"
+     And the output should not contain "after all in unfocused group"
+
+  Scenario: Use symbols as metadata
+    Given a file named "symbols_as_metadata_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.filter_run :current_example
+      end
+
+      RSpec.describe "something" do
+        it "does one thing" do
+        end
+
+        it "does another thing", :current_example do
+        end
+      end
+      """
+    When I run `rspec symbols_as_metadata_spec.rb --format doc`
+    Then the output should contain "does another thing"
+    And the output should not contain "does one thing"
diff --git a/rspec-core/features/formatters/configurable_colors.feature b/rspec-core/features/formatters/configurable_colors.feature
new file mode 100644
index 0000000..0ae855a
--- /dev/null
+++ b/rspec-core/features/formatters/configurable_colors.feature
@@ -0,0 +1,32 @@
+Feature: Configurable colors
+
+  RSpec allows you to configure the terminal colors used in the text formatters.
+
+  * `failure_color`: Color used when tests fail (default: `:red`)
+  * `success_color`: Color used when tests pass (default: `:green`)
+  * `pending_color`: Color used when tests are pending (default: `:yellow`)
+  * `fixed_color`: Color used when a pending block inside an example passes, but
+    was expected to fail (default: `:blue`)
+  * `detail_color`: Color used for miscellaneous test details (default: `:cyan`)
+
+  Colors are specified as symbols. Options are `:black`, `:red`, `:green`,
+  `:yellow`, `:blue`, `:magenta`, `:cyan`, and `:white`.
+
+  @ansi
+  Scenario: Customizing the failure color
+    Given a file named "custom_failure_color_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.failure_color = :magenta
+        config.tty = true
+        config.color = true
+      end
+
+      RSpec.describe "failure" do
+        it "fails and uses the custom color" do
+          expect(2).to eq(4)
+        end
+      end
+      """
+      When I run `rspec custom_failure_color_spec.rb --format progress`
+      Then the failing example is printed in magenta
diff --git a/rspec-core/features/formatters/custom_formatter.feature b/rspec-core/features/formatters/custom_formatter.feature
new file mode 100644
index 0000000..ae71b51
--- /dev/null
+++ b/rspec-core/features/formatters/custom_formatter.feature
@@ -0,0 +1,37 @@
+Feature: custom formatters
+
+  RSpec ships with general purpose output formatters. You can tell RSpec which
+  one to use using the [`--format` command line option](../command-line/format-option).
+
+  When RSpec's built-in output formatters don't, however, give you everything
+  you need, you can write your own custom formatter and tell RSpec to use that
+  one instead. The simplest way is to subclass RSpec's `BaseTextFormatter`, and
+  then override just the methods that you want to modify.
+
+  Scenario: Custom formatter
+    Given a file named "custom_formatter.rb" with:
+      """ruby
+      class CustomFormatter
+        # This registers the notifications this formatter supports, and tells
+        # us that this was written against the RSpec 3.x formatter API.
+        RSpec::Core::Formatters.register self, :example_started
+
+        def initialize(output)
+          @output = output
+        end
+
+        def example_started(notification)
+          @output << "example: " << notification.example.description
+        end
+      end
+      """
+    And a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "my group" do
+        specify "my example" do
+        end
+      end
+      """
+    When I run `rspec example_spec.rb --require ./custom_formatter.rb --format CustomFormatter`
+    Then the output should contain "example: my example"
+    And  the exit status should be 0
diff --git a/rspec-core/features/formatters/json_formatter.feature b/rspec-core/features/formatters/json_formatter.feature
new file mode 100644
index 0000000..71dc245
--- /dev/null
+++ b/rspec-core/features/formatters/json_formatter.feature
@@ -0,0 +1,30 @@
+Feature: JSON formatter
+
+  Scenario: Formatting example names for retry
+    Given a file named "various_spec.rb" with:
+    """ruby
+    RSpec.describe "Various" do
+      it "fails" do
+        expect("fail").to eq("succeed")
+      end
+
+      it "succeeds" do
+        expect("succeed").to eq("succeed")
+      end
+
+      it "pends"
+    end
+    """
+    When I run `rspec various_spec.rb --format j`
+    Then the output should contain all of these:
+          |"summary_line":"3 examples, 1 failure, 1 pending"|
+          |"examples":[                                     |
+          |"description":"fails"                             |
+          |"full_description":"Various fails"                |
+          |"status":"failed"                                 |
+          |"file_path":"./various_spec.rb"                   |
+          |"line_number":2                                   |
+          |"exception":{                                     |
+          |"class":"RSpec::Expectations::ExpectationNotMetError"|
+
+    And the exit status should be 1
diff --git a/rspec-core/features/helper_methods/arbitrary_methods.feature b/rspec-core/features/helper_methods/arbitrary_methods.feature
new file mode 100644
index 0000000..e9c241d
--- /dev/null
+++ b/rspec-core/features/helper_methods/arbitrary_methods.feature
@@ -0,0 +1,40 @@
+Feature: arbitrary helper methods
+
+  You can define methods in any example group using Ruby's `def` keyword or
+  `define_method` method. These _helper_ methods are exposed to examples in the
+  group in which they are defined and groups nested within that group, but not
+  parent or sibling groups.
+
+  Scenario: Use a method defined in the same group
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        def help
+          :available
+        end
+
+        it "has access to methods defined in its group" do
+          expect(help).to be(:available)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use a method defined in a parent group
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        def help
+          :available
+        end
+
+        describe "in a nested group" do
+          it "has access to methods defined in its parent group" do
+            expect(help).to be(:available)
+          end
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/helper_methods/let.feature b/rspec-core/features/helper_methods/let.feature
new file mode 100644
index 0000000..0417bd0
--- /dev/null
+++ b/rspec-core/features/helper_methods/let.feature
@@ -0,0 +1,50 @@
+Feature: let and let!
+
+  Use `let` to define a memoized helper method. The value will be cached across
+  multiple calls in the same example but not across examples.
+
+  Note that `let` is lazy-evaluated: it is not evaluated until the first time
+  the method it defines is invoked. You can use `let!` to force the method's
+  invocation before each example.
+
+  Scenario: Use `let` to define memoized helper method
+    Given a file named "let_spec.rb" with:
+      """ruby
+      $count = 0
+      RSpec.describe "let" do
+        let(:count) { $count += 1 }
+
+        it "memoizes the value" do
+          expect(count).to eq(1)
+          expect(count).to eq(1)
+        end
+
+        it "is not cached across examples" do
+          expect(count).to eq(2)
+        end
+      end
+      """
+    When I run `rspec let_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `let!` to define a memoized helper method that is called in a `before` hook
+    Given a file named "let_bang_spec.rb" with:
+      """ruby
+      $count = 0
+      RSpec.describe "let!" do
+        invocation_order = []
+
+        let!(:count) do
+          invocation_order << :let!
+          $count += 1
+        end
+
+        it "calls the helper method in a before hook" do
+          invocation_order << :example
+          expect(invocation_order).to eq([:let!, :example])
+          expect(count).to eq(1)
+        end
+      end
+      """
+    When I run `rspec let_bang_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/helper_methods/modules.feature b/rspec-core/features/helper_methods/modules.feature
new file mode 100644
index 0000000..b92070e
--- /dev/null
+++ b/rspec-core/features/helper_methods/modules.feature
@@ -0,0 +1,152 @@
+Feature: Define helper methods in a module
+
+  You can define helper methods in a module and include it in your example
+  groups using the `config.include` configuration option. `config.extend` can be
+  used to extend the module onto your example groups so that the methods in the
+  module are available in the example groups themselves (but not in the actual
+  examples).
+
+  You can also `include` or `extend` the module onto only certain example groups
+  by passing a metadata hash as the last argument. Only groups that match the
+  given metadata will `include` or `extend` the module. You can also specify
+  metadata using only symbols.
+
+  Note that examples that match a `config.include` module's metadata will also have the module included. RSpec treats every example as having a singleton example group (analogous to Ruby's singleton classes) containing just the one example.
+
+  Background:
+    Given a file named "helpers.rb" with:
+      """ruby
+      module Helpers
+        def help
+          :available
+        end
+      end
+      """
+
+  Scenario: Include a module in all example groups
+    Given a file named "include_module_spec.rb" with:
+      """ruby
+      require './helpers'
+
+      RSpec.configure do |c|
+        c.include Helpers
+      end
+
+      RSpec.describe "an example group" do
+        it "has access to the helper methods defined in the module" do
+          expect(help).to be(:available)
+        end
+      end
+      """
+    When I run `rspec include_module_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Extend a module in all example groups
+    Given a file named "extend_module_spec.rb" with:
+      """ruby
+      require './helpers'
+
+      RSpec.configure do |c|
+        c.extend Helpers
+      end
+
+      RSpec.describe "an example group" do
+        puts "Help is #{help}"
+
+        it "does not have access to the helper methods defined in the module" do
+          expect { help }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec extend_module_spec.rb`
+    Then the examples should all pass
+    And the output should contain "Help is available"
+
+  Scenario: Include a module in only some example groups
+    Given a file named "include_module_in_some_groups_spec.rb" with:
+      """ruby
+      require './helpers'
+
+      RSpec.configure do |c|
+        c.include Helpers, :foo => :bar
+      end
+
+      RSpec.describe "an example group with matching metadata", :foo => :bar do
+        it "has access to the helper methods defined in the module" do
+          expect(help).to be(:available)
+        end
+      end
+
+      RSpec.describe "an example group without matching metadata" do
+        it "does not have access to the helper methods defined in the module" do
+          expect { help }.to raise_error(NameError)
+        end
+
+        it "does have access when the example has matching metadata", :foo => :bar do
+          expect(help).to be(:available)
+        end
+      end
+      """
+    When I run `rspec include_module_in_some_groups_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Extend a module in only some example groups
+    Given a file named "extend_module_in_only_some_groups_spec.rb" with:
+      """ruby
+      require './helpers'
+
+      RSpec.configure do |c|
+        c.extend Helpers, :foo => :bar
+      end
+
+      RSpec.describe "an example group with matching metadata", :foo => :bar do
+        puts "In a matching group, help is #{help}"
+
+        it "does not have access to the helper methods defined in the module" do
+          expect { help }.to raise_error(NameError)
+        end
+      end
+
+      RSpec.describe "an example group without matching metadata" do
+        puts "In a non-matching group, help is #{help rescue 'not available'}"
+
+        it "does not have access to the helper methods defined in the module" do
+          expect { help }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec extend_module_in_only_some_groups_spec.rb`
+    Then the examples should all pass
+    And the output should contain "In a matching group, help is available"
+    And the output should contain "In a non-matching group, help is not available"
+
+  Scenario: Use symbols as metadata
+    Given a file named "symbols_as_metadata_spec.rb" with:
+      """ruby
+      require './helpers'
+
+      RSpec.configure do |c|
+        c.include Helpers, :include_helpers
+        c.extend  Helpers, :extend_helpers
+      end
+
+      RSpec.describe "an example group with matching include metadata", :include_helpers do
+        puts "In a group not matching the extend filter, help is #{help rescue 'not available'}"
+
+        it "has access to the helper methods defined in the module" do
+          expect(help).to be(:available)
+        end
+      end
+
+      RSpec.describe "an example group with matching extend metadata", :extend_helpers do
+        puts "In a group matching the extend filter, help is #{help}"
+
+        it "does not have access to the helper methods defined in the module" do
+          expect { help }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec symbols_as_metadata_spec.rb`
+    Then the examples should all pass
+    And the output should contain "In a group not matching the extend filter, help is not available"
+    And the output should contain "In a group matching the extend filter, help is available"
diff --git a/rspec-core/features/hooks/around_hooks.feature b/rspec-core/features/hooks/around_hooks.feature
new file mode 100644
index 0000000..99a76d9
--- /dev/null
+++ b/rspec-core/features/hooks/around_hooks.feature
@@ -0,0 +1,372 @@
+Feature: `around` hooks
+
+  `around` hooks receive the example as a block argument, extended to behave as
+  a proc. This lets you define code that should be executed before and after the
+  example. Of course, you can do the same thing with `before` and `after` hooks;
+  and it's often cleaner to do so.
+
+  Where `around` hooks shine is when you want to run an example within a block.
+  For instance, if your database library offers a transaction method that
+  receives a block, you can use an `around` to cleanly open and close the
+  transaction around the example.
+
+  **WARNING:** `around` hooks do not share state with the example the way
+  `before` and `after` hooks do. This means that you cannot share instance
+  variables between `around` hooks and examples.
+
+  **WARNING:** Mock frameworks are set up and torn down within the context of
+  running the example. You cannot interact with them directly in `around` hooks.
+
+  Scenario: Use the example as a proc within the block passed to `around()`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      class Database
+        def self.transaction
+          puts "open transaction"
+          yield
+          puts "close transaction"
+        end
+      end
+
+      RSpec.describe "around filter" do
+        around(:example) do |example|
+          Database.transaction(&example)
+        end
+
+        it "gets run in order" do
+          puts "run the example"
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain:
+      """
+      open transaction
+      run the example
+      close transaction
+      """
+
+  Scenario: Invoke the example using `run()`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "around hook" do
+        around(:example) do |example|
+          puts "around example before"
+          example.run
+          puts "around example after"
+        end
+
+        it "gets run in order" do
+          puts "in the example"
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain:
+      """
+      around example before
+      in the example
+      around example after
+      """
+
+  Scenario: Access the example metadata
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        around(:example) do |example|
+          puts example.metadata[:foo]
+          example.run
+        end
+
+        it "does something", :foo => "this should show up in the output" do
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "this should show up in the output"
+
+  Scenario: An around hook continues to run even if the example throws an exception
+    Given a file named "example_spec.rb" with:
+      """ruby
+        RSpec.describe "something" do
+          around(:example) do |example|
+            puts "around example setup"
+            example.run
+            puts "around example cleanup"
+          end
+
+          it "still executes the entire around hook" do
+            fail "the example blows up"
+          end
+        end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain:
+      """
+      around example setup
+      around example cleanup
+      """
+
+  Scenario: Define a global `around` hook
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.around(:example) do |example|
+          puts "around example before"
+          example.run
+          puts "around example after"
+        end
+      end
+
+      RSpec.describe "around filter" do
+        it "gets run in order" do
+          puts "in the example"
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain:
+      """
+      around example before
+      in the example
+      around example after
+      """
+
+  Scenario: Per example hooks are wrapped by the `around` hook
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "around filter" do
+        around(:example) do |example|
+          puts "around example before"
+          example.run
+          puts "around example after"
+        end
+
+        before(:example) do
+          puts "before example"
+        end
+
+        after(:example) do
+          puts "after example"
+        end
+
+        it "gets run in order" do
+          puts "in the example"
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain:
+      """
+      around example before
+      before example
+      in the example
+      after example
+      around example after
+      """
+
+  Scenario: Context hooks are NOT wrapped by the `around` hook
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "around filter" do
+        around(:example) do |example|
+          puts "around example before"
+          example.run
+          puts "around example after"
+        end
+
+        before(:context) do
+          puts "before context"
+        end
+
+        after(:context) do
+          puts "after context"
+        end
+
+        it "gets run in order" do
+          puts "in the example"
+        end
+      end
+      """
+    When I run `rspec --format progress example_spec.rb`
+    Then the output should contain:
+      """
+      before context
+      around example before
+      in the example
+      around example after
+      .after context
+      """
+
+  Scenario: Examples run by an `around` block are run in the configured context
+    Given a file named "example_spec.rb" with:
+      """ruby
+      module IncludedInConfigureBlock
+        def included_in_configure_block; true; end
+      end
+
+      RSpec.configure do |c|
+        c.include IncludedInConfigureBlock
+      end
+
+      RSpec.describe "around filter" do
+        around(:example) do |example|
+          example.run
+        end
+
+        it "runs the example in the correct context" do
+          expect(included_in_configure_block).to be_truthy
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failure"
+
+  Scenario: Implicitly pending examples are detected as Not yet implemented
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "implicit pending example" do
+        around(:example) do |example|
+          example.run
+        end
+
+        it "should be detected as Not yet implemented"
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) implicit pending example should be detected as Not yet implemented
+           # Not yet implemented
+           # ./example_spec.rb:6
+      """
+
+
+  Scenario: Explicitly pending examples are detected as pending
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "explicit pending example" do
+        around(:example) do |example|
+          example.run
+        end
+
+        it "should be detected as pending" do
+          pending
+          fail
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) explicit pending example should be detected as pending
+           # No reason given
+      """
+
+  Scenario: Multiple `around` hooks in the same scope
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "if there are multiple around hooks in the same scope" do
+        around(:example) do |example|
+          puts "first around hook before"
+          example.run
+          puts "first around hook after"
+        end
+
+        around(:example) do |example|
+          puts "second around hook before"
+          example.run
+          puts "second around hook after"
+        end
+
+        it "they should all be run" do
+          puts "in the example"
+          expect(1).to eq(1)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failure"
+    And the output should contain:
+      """
+      first around hook before
+      second around hook before
+      in the example
+      second around hook after
+      first around hook after
+      """
+
+  Scenario: `around` hooks in multiple scopes
+    Given a file named "example_spec.rb" with:
+    """ruby
+    RSpec.describe "if there are around hooks in an outer scope" do
+      around(:example) do |example|
+        puts "first outermost around hook before"
+        example.run
+        puts "first outermost around hook after"
+      end
+
+      around(:example) do |example|
+        puts "second outermost around hook before"
+        example.run
+        puts "second outermost around hook after"
+      end
+
+      describe "outer scope" do
+        around(:example) do |example|
+          puts "first outer around hook before"
+          example.run
+          puts "first outer around hook after"
+        end
+
+        around(:example) do |example|
+          puts "second outer around hook before"
+          example.run
+          puts "second outer around hook after"
+        end
+
+        describe "inner scope" do
+          around(:example) do |example|
+            puts "first inner around hook before"
+            example.run
+            puts "first inner around hook after"
+          end
+
+          around(:example) do |example|
+            puts "second inner around hook before"
+            example.run
+            puts "second inner around hook after"
+          end
+
+          it "they should all be run" do
+            puts "in the example"
+          end
+        end
+      end
+    end
+    """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failure"
+    And the output should contain:
+    """
+    first outermost around hook before
+    second outermost around hook before
+    first outer around hook before
+    second outer around hook before
+    first inner around hook before
+    second inner around hook before
+    in the example
+    second inner around hook after
+    first inner around hook after
+    second outer around hook after
+    first outer around hook after
+    second outermost around hook after
+    first outermost around hook after
+    """
diff --git a/rspec-core/features/hooks/before_and_after_hooks.feature b/rspec-core/features/hooks/before_and_after_hooks.feature
new file mode 100644
index 0000000..9c6e0dd
--- /dev/null
+++ b/rspec-core/features/hooks/before_and_after_hooks.feature
@@ -0,0 +1,434 @@
+Feature: `before` and `after` hooks
+
+  Use `before` and `after` hooks to execute arbitrary code before and/or after
+  the body of an example is run:
+
+  ```ruby
+  before(:example) # run before each example
+  before(:context) # run one time only, before all of the examples in a group
+
+  after(:example) # run after each example
+  after(:context) # run one time only, after all of the examples in a group
+  ```
+
+  `before` and `after` blocks are called in the following order:
+
+  ```ruby
+  before :suite
+  before :context
+  before :example
+  after  :example
+  after  :context
+  after  :suite
+  ```
+
+  `before` and `after` hooks can be defined directly in the example groups they
+  should run in, or in a global `RSpec.configure` block.
+
+  **WARNING:** Setting instance variables are not supported in `before(:suite)`.
+
+  **WARNING:** Mocks are only supported in `before(:example)`.
+
+  Note: the `:example` and `:context` scopes are also available as `:each` and
+  `:all`, respectively. Use whichever you prefer.
+
+  Scenario: Define `before(:example)` block
+    Given a file named "before_example_spec.rb" with:
+      """ruby
+      require "rspec/expectations"
+
+      class Thing
+        def widgets
+          @widgets ||= []
+        end
+      end
+
+      RSpec.describe Thing do
+        before(:example) do
+          @thing = Thing.new
+        end
+
+        describe "initialized in before(:example)" do
+          it "has 0 widgets" do
+            expect(@thing.widgets.count).to eq(0)
+          end
+
+          it "can accept new widgets" do
+            @thing.widgets << Object.new
+          end
+
+          it "does not share state across examples" do
+            expect(@thing.widgets.count).to eq(0)
+          end
+        end
+      end
+      """
+    When I run `rspec before_example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Define `before(:context)` block in example group
+    Given a file named "before_context_spec.rb" with:
+      """ruby
+      require "rspec/expectations"
+
+      class Thing
+        def widgets
+          @widgets ||= []
+        end
+      end
+
+      RSpec.describe Thing do
+        before(:context) do
+          @thing = Thing.new
+        end
+
+        describe "initialized in before(:context)" do
+          it "has 0 widgets" do
+            expect(@thing.widgets.count).to eq(0)
+          end
+
+          it "can accept new widgets" do
+            @thing.widgets << Object.new
+          end
+
+          it "shares state across examples" do
+            expect(@thing.widgets.count).to eq(1)
+          end
+        end
+      end
+      """
+    When I run `rspec before_context_spec.rb`
+    Then the examples should all pass
+
+    When I run `rspec before_context_spec.rb:15`
+    Then the examples should all pass
+
+  Scenario: Failure in `before(:context)` block
+    Given a file named "before_context_spec.rb" with:
+      """ruby
+      RSpec.describe "an error in before(:context)" do
+        before(:context) do
+          raise "oops"
+        end
+
+        it "fails this example" do
+        end
+
+        it "fails this example, too" do
+        end
+
+        after(:context) do
+          puts "after context ran"
+        end
+
+        describe "nested group" do
+          it "fails this third example" do
+          end
+
+          it "fails this fourth example" do
+          end
+
+          describe "yet another level deep" do
+            it "fails this last example" do
+            end
+          end
+        end
+      end
+      """
+    When I run `rspec before_context_spec.rb --format documentation`
+    Then the output should contain "5 examples, 5 failures"
+    And the output should contain:
+      """
+      an error in before(:context)
+        fails this example (FAILED - 1)
+        fails this example, too (FAILED - 2)
+        nested group
+          fails this third example (FAILED - 3)
+          fails this fourth example (FAILED - 4)
+          yet another level deep
+            fails this last example (FAILED - 5)
+      after context ran
+      """
+
+    When I run `rspec before_context_spec.rb:9 --format documentation`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain:
+      """
+      an error in before(:context)
+        fails this example, too (FAILED - 1)
+      """
+
+  Scenario: Failure in `after(:context)` block
+    Given a file named "after_context_spec.rb" with:
+      """ruby
+      RSpec.describe "an error in after(:context)" do
+        after(:context) do
+          raise StandardError.new("Boom!")
+        end
+
+        it "passes this example" do
+        end
+
+        it "passes this example, too" do
+        end
+      end
+      """
+    When I run `rspec after_context_spec.rb`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      An error occurred in an `after(:context)` hook.
+        StandardError: Boom!
+      """
+
+  Scenario: Define `before` and `after` blocks in configuration
+    Given a file named "befores_in_configuration_spec.rb" with:
+      """ruby
+      require "rspec/expectations"
+
+      RSpec.configure do |config|
+        config.before(:example) do
+          @before_example = "before example"
+        end
+        config.before(:context) do
+          @before_context = "before context"
+        end
+      end
+
+      RSpec.describe "stuff in before blocks" do
+        describe "with :context" do
+          it "should be available in the example" do
+            expect(@before_context).to eq("before context")
+          end
+        end
+        describe "with :example" do
+          it "should be available in the example" do
+            expect(@before_example).to eq("before example")
+          end
+        end
+      end
+      """
+    When I run `rspec befores_in_configuration_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `before`/`after` blocks are run in order
+    Given a file named "ensure_block_order_spec.rb" with:
+      """ruby
+      require "rspec/expectations"
+
+      RSpec.describe "before and after callbacks" do
+        before(:context) do
+          puts "before context"
+        end
+
+        before(:example) do
+          puts "before example"
+        end
+
+        after(:example) do
+          puts "after example"
+        end
+
+        after(:context) do
+          puts "after context"
+        end
+
+        it "gets run in order" do
+
+        end
+      end
+      """
+    When I run `rspec --format progress ensure_block_order_spec.rb`
+    Then the output should contain:
+      """
+      before context
+      before example
+      after example
+      .after context
+      """
+
+  Scenario: `before`/after` blocks defined in configuration are run in order
+    Given a file named "configuration_spec.rb" with:
+      """ruby
+      require "rspec/expectations"
+
+      RSpec.configure do |config|
+        config.before(:suite) do
+          puts "before suite"
+        end
+
+        config.before(:context) do
+          puts "before context"
+        end
+
+        config.before(:example) do
+          puts "before example"
+        end
+
+        config.after(:example) do
+          puts "after example"
+        end
+
+        config.after(:context) do
+          puts "after context"
+        end
+
+        config.after(:suite) do
+          puts "after suite"
+        end
+      end
+
+      RSpec.describe "ignore" do
+        example "ignore" do
+        end
+      end
+      """
+    When I run `rspec --format progress configuration_spec.rb`
+    Then the output should contain:
+      """
+      before suite
+      before context
+      before example
+      after example
+      .after context
+      after suite
+      """
+
+  Scenario: `before`/`after` context blocks are run once
+    Given a file named "before_and_after_context_spec.rb" with:
+      """ruby
+      RSpec.describe "before and after callbacks" do
+        before(:context) do
+          puts "outer before context"
+        end
+
+        example "in outer group" do
+        end
+
+        after(:context) do
+          puts "outer after context"
+        end
+
+        describe "nested group" do
+          before(:context) do
+            puts "inner before context"
+          end
+
+          example "in nested group" do
+          end
+
+          after(:context) do
+            puts "inner after context"
+          end
+        end
+
+      end
+      """
+    When I run `rspec --format progress before_and_after_context_spec.rb`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      outer before context
+      .inner before context
+      .inner after context
+      outer after context
+      """
+
+    When I run `rspec --format progress before_and_after_context_spec.rb:14`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      outer before context
+      inner before context
+      .inner after context
+      outer after context
+      """
+
+    When I run `rspec --format progress before_and_after_context_spec.rb:6`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      outer before context
+      .outer after context
+      """
+
+  Scenario: Nested examples have access to state set in outer `before(:context)`
+    Given a file named "before_context_spec.rb" with:
+      """ruby
+      RSpec.describe "something" do
+        before :context do
+          @value = 123
+        end
+
+        describe "nested" do
+          it "access state set in before(:context)" do
+            expect(@value).to eq(123)
+          end
+
+          describe "nested more deeply" do
+            it "access state set in before(:context)" do
+              expect(@value).to eq(123)
+            end
+          end
+        end
+
+        describe "nested in parallel" do
+          it "access state set in before(:context)" do
+            expect(@value).to eq(123)
+          end
+        end
+      end
+      """
+    When I run `rspec before_context_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `before`/`after` context blocks have access to state
+    Given a file named "before_and_after_context_spec.rb" with:
+      """ruby
+      RSpec.describe "before and after callbacks" do
+        before(:context) do
+          @outer_state = "set in outer before context"
+        end
+
+        example "in outer group" do
+          expect(@outer_state).to eq("set in outer before context")
+        end
+
+        describe "nested group" do
+          before(:context) do
+            @inner_state = "set in inner before context"
+          end
+
+          example "in nested group" do
+            expect(@outer_state).to eq("set in outer before context")
+            expect(@inner_state).to eq("set in inner before context")
+          end
+
+          after(:context) do
+            expect(@inner_state).to eq("set in inner before context")
+          end
+        end
+
+        after(:context) do
+          expect(@outer_state).to eq("set in outer before context")
+        end
+      end
+      """
+    When I run `rspec before_and_after_context_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Exception in `before(:example)` is captured and reported as failure
+    Given a file named "error_in_before_example_spec.rb" with:
+      """ruby
+      RSpec.describe "error in before(:example)" do
+        before(:example) do
+          raise "this error"
+        end
+
+        it "is reported as failure" do
+        end
+      end
+      """
+    When I run `rspec error_in_before_example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "this error"
diff --git a/rspec-core/features/hooks/filtering.feature b/rspec-core/features/hooks/filtering.feature
new file mode 100644
index 0000000..abdb12b
--- /dev/null
+++ b/rspec-core/features/hooks/filtering.feature
@@ -0,0 +1,246 @@
+Feature: filters
+
+  `before`, `after`, and `around` hooks defined in the block passed to
+  `RSpec.configure` can be constrained to specific examples and/or groups using
+  metadata as a filter.
+
+  ```ruby
+  RSpec.configure do |c|
+    c.before(:example, :type => :model) do
+    end
+  end
+
+  RSpec.describe "something", :type => :model do
+  end
+  ```
+
+  Note that filtered `:context` hooks will still be applied to individual examples with matching metadata -- in effect, every example has a singleton example group containing just the one example (analogous to Ruby's singleton classes).
+
+  You can also specify metadata using only symbols.
+
+  Scenario: Filter `before(:example)` hooks using arbitrary metadata
+    Given a file named "filter_before_example_hooks_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.before(:example, :foo => :bar) do
+          invoked_hooks << :before_example_foo_bar
+        end
+      end
+
+      RSpec.describe "a filtered before :example hook" do
+        let(:invoked_hooks) { [] }
+
+        describe "group without matching metadata" do
+          it "does not run the hook" do
+            expect(invoked_hooks).to be_empty
+          end
+
+          it "runs the hook for an example with matching metadata", :foo => :bar do
+            expect(invoked_hooks).to eq([:before_example_foo_bar])
+          end
+        end
+
+        describe "group with matching metadata", :foo => :bar do
+          it "runs the hook" do
+            expect(invoked_hooks).to eq([:before_example_foo_bar])
+          end
+        end
+      end
+      """
+    When I run `rspec filter_before_example_hooks_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Filter `after(:example)` hooks using arbitrary metadata
+    Given a file named "filter_after_example_hooks_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.after(:example, :foo => :bar) do
+          raise "boom!"
+        end
+      end
+
+      RSpec.describe "a filtered after :example hook" do
+        describe "group without matching metadata" do
+          it "does not run the hook" do
+            # should pass
+          end
+
+          it "runs the hook for an example with matching metadata", :foo => :bar do
+            # should fail
+          end
+        end
+
+        describe "group with matching metadata", :foo => :bar do
+          it "runs the hook" do
+            # should fail
+          end
+        end
+      end
+      """
+    When I run `rspec filter_after_example_hooks_spec.rb`
+    Then the output should contain "3 examples, 2 failures"
+
+  Scenario: Filter `around(:example)` hooks using arbitrary metadata
+    Given a file named "filter_around_example_hooks_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.around(:example, :foo => :bar) do |example|
+          order << :before_around_example_foo_bar
+          example.run
+          expect(order).to eq([:before_around_example_foo_bar, :example])
+        end
+      end
+
+      RSpec.describe "a filtered around(:example) hook" do
+        let(:order) { [] }
+
+        describe "a group without matching metadata" do
+          it "does not run the hook" do
+            expect(order).to be_empty
+          end
+
+          it "runs the hook for an example with matching metadata", :foo => :bar do
+            expect(order).to eq([:before_around_example_foo_bar])
+            order << :example
+          end
+        end
+
+        describe "a group with matching metadata", :foo => :bar do
+          it "runs the hook for an example with matching metadata", :foo => :bar do
+            expect(order).to eq([:before_around_example_foo_bar])
+            order << :example
+          end
+        end
+      end
+      """
+    When I run `rspec filter_around_example_hooks_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Filter `before(:context)` hooks using arbitrary metadata
+    Given a file named "filter_before_context_hooks_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.before(:context, :foo => :bar) { @hook = :before_context_foo_bar }
+      end
+
+      RSpec.describe "a filtered before(:context) hook" do
+        describe "a group without matching metadata" do
+          it "does not run the hook" do
+            expect(@hook).to be_nil
+          end
+
+          it "runs the hook for a single example with matching metadata", :foo => :bar do
+            expect(@hook).to eq(:before_context_foo_bar)
+          end
+
+          describe "a nested subgroup with matching metadata", :foo => :bar do
+            it "runs the hook" do
+              expect(@hook).to eq(:before_context_foo_bar)
+            end
+          end
+        end
+
+        describe "a group with matching metadata", :foo => :bar do
+          it "runs the hook" do
+            expect(@hook).to eq(:before_context_foo_bar)
+          end
+
+          describe "a nested subgroup" do
+            it "runs the hook" do
+              expect(@hook).to eq(:before_context_foo_bar)
+            end
+          end
+        end
+      end
+      """
+    When I run `rspec filter_before_context_hooks_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Filter `after(:context)` hooks using arbitrary metadata
+    Given a file named "filter_after_context_hooks_spec.rb" with:
+      """ruby
+      example_msgs = []
+
+      RSpec.configure do |config|
+        config.after(:context, :foo => :bar) do
+          puts "after :context"
+        end
+      end
+
+      RSpec.describe "a filtered after(:context) hook" do
+        describe "a group without matching metadata" do
+          it "does not run the hook" do
+            puts "unfiltered"
+          end
+
+          it "runs the hook for a single example with matching metadata", :foo => :bar do
+            puts "filtered 1"
+          end
+        end
+
+        describe "a group with matching metadata", :foo => :bar do
+          it "runs the hook" do
+            puts "filtered 2"
+          end
+        end
+
+        describe "another group without matching metadata" do
+          describe "a nested subgroup with matching metadata", :foo => :bar do
+            it "runs the hook" do
+              puts "filtered 3"
+            end
+          end
+        end
+      end
+      """
+    When I run `rspec --format progress filter_after_context_hooks_spec.rb --order defined`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      unfiltered
+      .filtered 1
+      after :context
+      .filtered 2
+      .after :context
+      filtered 3
+      .after :context
+      """
+
+  Scenario: Use symbols as metadata
+    Given a file named "less_verbose_metadata_filter.rb" with:
+      """ruby
+      RSpec.configure do |c|
+        c.before(:example, :before_example) { puts "before example" }
+        c.after(:example,  :after_example) { puts "after example" }
+        c.around(:example, :around_example) do |example|
+          puts "around example (before)"
+          example.run
+          puts "around example (after)"
+        end
+        c.before(:context, :before_context) { puts "before context" }
+        c.after(:context,  :after_context) { puts "after context" }
+      end
+
+      RSpec.describe "group 1", :before_context, :after_context do
+        it("") { puts "example 1" }
+        it("", :before_example) { puts "example 2" }
+        it("", :after_example) { puts "example 3" }
+        it("", :around_example) { puts "example 4" }
+      end
+      """
+    When I run `rspec --format progress less_verbose_metadata_filter.rb`
+    Then the examples should all pass
+    And the output should contain:
+      """
+      before context
+      example 1
+      .before example
+      example 2
+      .example 3
+      after example
+      .around example (before)
+      example 4
+      around example (after)
+      .after context
+      """
+
diff --git a/rspec-core/features/metadata/current_example.feature b/rspec-core/features/metadata/current_example.feature
new file mode 100644
index 0000000..abe33fe
--- /dev/null
+++ b/rspec-core/features/metadata/current_example.feature
@@ -0,0 +1,57 @@
+Feature: current example
+
+  You can reference the example object, and access its metadata, using the block
+  argument provided to: `it`, `subject`, `let`, and the `before`, `after`, and
+  `around` hooks.
+
+  Scenario: Access the `example` object from within an example
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "example as block arg to it, before, and after" do
+        before do |example|
+          expect(example.description).to eq("is the example object")
+        end
+
+        after do |example|
+          expect(example.description).to eq("is the example object")
+        end
+
+        it "is the example object" do |example|
+          expect(example.description).to eq("is the example object")
+        end
+      end
+
+      RSpec.describe "example as block arg to let" do
+        let(:the_description) do |example|
+          example.description
+        end
+
+        it "is the example object" do |example|
+          expect(the_description).to eq("is the example object")
+        end
+      end
+
+      RSpec.describe "example as block arg to subject" do
+        subject do |example|
+          example.description
+        end
+
+        it "is the example object" do |example|
+          expect(subject).to eq("is the example object")
+        end
+      end
+
+      RSpec.describe "example as block arg to subject with a name" do
+        subject(:the_subject) do |example|
+          example.description
+        end
+
+        it "is the example object" do |example|
+          expect(the_subject).to eq("is the example object")
+          expect(subject).to eq("is the example object")
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the example should pass
+
diff --git a/rspec-core/features/metadata/described_class.feature b/rspec-core/features/metadata/described_class.feature
new file mode 100644
index 0000000..3a4c176
--- /dev/null
+++ b/rspec-core/features/metadata/described_class.feature
@@ -0,0 +1,17 @@
+Feature: described class
+
+  If the first argument to the outermost example group is a class, the class is
+  exposed to each example via the `described_class()` method.
+
+  Scenario: Access the described class from the example
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe Fixnum do
+        it "is available as described_class" do
+          expect(described_class).to eq(Fixnum)
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the example should pass
+
diff --git a/rspec-core/features/metadata/user_defined.feature b/rspec-core/features/metadata/user_defined.feature
new file mode 100644
index 0000000..b235035
--- /dev/null
+++ b/rspec-core/features/metadata/user_defined.feature
@@ -0,0 +1,100 @@
+Feature: User-defined metadata
+
+  You can attach user-defined metadata to any example group or example. Pass a
+  hash as the last argument (before the block) to `describe`, `context` or `it`.
+  RSpec supports many configuration options that apply only to certain examples
+  or groups based on the metadata.
+
+  Metadata defined on an example group is available (and can be overridden) by
+  any sub-group or from any example in that group or a sub-group.
+
+  In addition, you can specify metdata using just symbols. Each symbol passed
+  as an argument to `describe`, `context` or `it` will be a key in the metadata
+  hash, with a corresponding value of `true`.
+
+  Scenario: Define group metadata using a hash
+    Given a file named "define_group_metadata_with_hash_spec.rb" with:
+      """ruby
+      RSpec.describe "a group with user-defined metadata", :foo => 17 do
+        it 'has access to the metadata in the example' do |example|
+          expect(example.metadata[:foo]).to eq(17)
+        end
+
+        it 'does not have access to metadata defined on sub-groups' do |example|
+          expect(example.metadata).not_to include(:bar)
+        end
+
+        describe 'a sub-group with user-defined metadata', :bar => 12 do
+          it 'has access to the sub-group metadata' do |example|
+            expect(example.metadata[:bar]).to eq(12)
+          end
+
+          it 'also has access to metadata defined on parent groups' do |example|
+            expect(example.metadata[:foo]).to eq(17)
+          end
+        end
+      end
+      """
+    When I run `rspec define_group_metadata_with_hash_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Define example metadata using a hash
+    Given a file named "define_example_metadata_with_hash_spec.rb" with:
+      """ruby
+      RSpec.describe "a group with no user-defined metadata" do
+        it 'has an example with metadata', :foo => 17 do |example|
+          expect(example.metadata[:foo]).to eq(17)
+          expect(example.metadata).not_to include(:bar)
+        end
+
+        it 'has another example with metadata', :bar => 12, :bazz => 33 do |example|
+          expect(example.metadata[:bar]).to eq(12)
+          expect(example.metadata[:bazz]).to eq(33)
+          expect(example.metadata).not_to include(:foo)
+        end
+      end
+      """
+    When I run `rspec define_example_metadata_with_hash_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Override user-defined metadata
+    Given a file named "override_metadata_spec.rb" with:
+      """ruby
+      RSpec.describe "a group with user-defined metadata", :foo => 'bar' do
+        it 'can be overridden by an example', :foo => 'bazz' do |example|
+          expect(example.metadata[:foo]).to eq('bazz')
+        end
+
+        describe "a sub-group with an override", :foo => 'goo' do
+          it 'can be overridden by a sub-group' do |example|
+            expect(example.metadata[:foo]).to eq('goo')
+          end
+        end
+      end
+      """
+    When I run `rspec override_metadata_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Less verbose metadata
+    Given a file named "less_verbose_metadata_spec.rb" with:
+      """ruby
+      RSpec.describe "a group with simple metadata", :fast, :simple, :bug => 73 do
+        it 'has `:fast => true` metadata' do |example|
+          expect(example.metadata[:fast]).to eq(true)
+        end
+
+        it 'has `:simple => true` metadata' do |example|
+          expect(example.metadata[:simple]).to eq(true)
+        end
+
+        it 'can still use a hash for metadata' do |example|
+          expect(example.metadata[:bug]).to eq(73)
+        end
+
+        it 'can define simple metadata on an example', :special do |example|
+          expect(example.metadata[:special]).to eq(true)
+        end
+      end
+      """
+    When I run `rspec less_verbose_metadata_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/mock_framework_integration/use_any_framework.feature b/rspec-core/features/mock_framework_integration/use_any_framework.feature
new file mode 100644
index 0000000..ce88e10
--- /dev/null
+++ b/rspec-core/features/mock_framework_integration/use_any_framework.feature
@@ -0,0 +1,106 @@
+Feature: mock with an alternative framework
+
+  In addition to rspec, mocha, flexmock, and RR, you can choose an alternate
+  framework as the mocking framework. You (or the framework authors) just needs
+  to provide an adapter that hooks RSpec's events into those of the framework.
+
+  A mock framework adapter must expose three methods:
+
+  * `setup_mocks_for_rspec`
+    * called before each example is run
+  * `verify_mocks_for_rspec`
+    * called after each example is run
+    * this is where message expectation failures should result in an error with
+      the appropriate failure message
+  * `teardown_mocks_for_rspec`
+    * called after `verify_mocks_for_rspec`
+    * use this to clean up resources, restore objects to earlier state, etc
+    * guaranteed to run even if there are failures
+
+  Scenario: Mock with alternate framework
+    Given a file named "expector.rb" with:
+      """ruby
+      class Expector
+        class << self
+          def expectors
+            @expectors ||= []
+          end
+
+          def clear_expectors
+            expectors.clear
+          end
+
+          def verify_expectors
+            expectors.each {|d| d.verify}
+          end
+        end
+
+        def initialize
+          self.class.expectors << self
+        end
+
+        def expectations
+          @expectations ||= []
+        end
+
+        def expect(message)
+          expectations << message.to_s
+        end
+
+        def verify
+          unless expectations.empty?
+            raise expectations.map {|e|
+              "expected #{e}, but it was never received"
+            }.join("\n")
+          end
+        end
+
+      private
+
+        def method_missing(name, *args, &block)
+          expectations.delete(name.to_s)
+        end
+
+      public
+
+        module RSpecAdapter
+          def setup_mocks_for_rspec
+            # no setup necessary
+          end
+
+          def verify_mocks_for_rspec
+            Expector.verify_expectors
+          end
+
+          def teardown_mocks_for_rspec
+            Expector.clear_expectors
+          end
+        end
+      end
+      """
+
+    Given a file named "example_spec.rb" with:
+      """ruby
+      require File.expand_path("../expector", __FILE__)
+
+      RSpec.configure do |config|
+        config.mock_framework = Expector::RSpecAdapter
+      end
+
+      RSpec.describe Expector do
+        it "passes when message is received" do
+          expector = Expector.new
+          expector.expect(:foo)
+          expector.foo
+        end
+
+        it "fails when message is received" do
+          expector = Expector.new
+          expector.expect(:foo)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb --format doc`
+    Then the exit status should be 1
+    And the output should contain "2 examples, 1 failure"
+    And the output should contain "fails when message is received (FAILED - 1)"
diff --git a/rspec-core/features/mock_framework_integration/use_flexmock.feature b/rspec-core/features/mock_framework_integration/use_flexmock.feature
new file mode 100644
index 0000000..c709a0b
--- /dev/null
+++ b/rspec-core/features/mock_framework_integration/use_flexmock.feature
@@ -0,0 +1,94 @@
+Feature: mock with flexmock
+
+  Configure RSpec to use flexmock as shown in the scenarios below.
+
+  Scenario: Passing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :flexmock
+      end
+
+      RSpec.describe "mocking with Flexmock" do
+        it "passes when it should" do
+          receiver = flexmock('receiver')
+          receiver.should_receive(:message).once
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :flexmock
+      end
+
+      RSpec.describe "mocking with Flexmock" do
+        it "fails when it should" do
+          receiver = flexmock('receiver')
+          receiver.should_receive(:message).once
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+
+  Scenario: Failing message expectation in pending example (remains pending)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :flexmock
+      end
+
+      RSpec.describe "failed message expectation in a pending example" do
+        it "is listed as pending" do
+          pending
+          receiver = flexmock('receiver')
+          receiver.should_receive(:message).once
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failures, 1 pending"
+    And the exit status should be 0
+
+  Scenario: Passing message expectation in pending example (fails)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :flexmock
+      end
+
+      RSpec.describe "passing message expectation in a pending example" do
+        it "fails with FIXED" do
+          pending
+          receiver = flexmock('receiver')
+          receiver.should_receive(:message).once
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "FIXED"
+    Then the output should contain "1 example, 1 failure"
+    And the exit status should be 1
+
+  Scenario: Accessing `RSpec.configuration.mock_framework.framework_name`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :flexmock
+      end
+
+      RSpec.describe "RSpec.configuration.mock_framework.framework_name" do
+        it "returns :flexmock" do
+          expect(RSpec.configuration.mock_framework.framework_name).to eq(:flexmock)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/mock_framework_integration/use_mocha.feature b/rspec-core/features/mock_framework_integration/use_mocha.feature
new file mode 100644
index 0000000..750db2c
--- /dev/null
+++ b/rspec-core/features/mock_framework_integration/use_mocha.feature
@@ -0,0 +1,95 @@
+Feature: mock with mocha
+
+  Configure RSpec to use mocha as shown in the scenarios below.
+
+  Scenario: Passing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :mocha
+      end
+
+      RSpec.describe "mocking with RSpec" do
+        it "passes when it should" do
+          receiver = mock('receiver')
+          receiver.expects(:message).once
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :mocha
+      end
+
+      RSpec.describe "mocking with RSpec" do
+        it "fails when it should" do
+          receiver = mock('receiver')
+          receiver.expects(:message).once
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+
+  Scenario: Failing message expectation in pending example (remains pending)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :mocha
+      end
+
+      RSpec.describe "failed message expectation in a pending example" do
+        it "is listed as pending" do
+          pending
+          receiver = mock('receiver')
+          receiver.expects(:message).once
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failures, 1 pending"
+    And the exit status should be 0
+
+  Scenario: Passing message expectation in pending example (fails)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :mocha
+      end
+
+      RSpec.describe "passing message expectation in a pending example" do
+        it "fails with FIXED" do
+          pending
+          receiver = mock('receiver')
+          receiver.expects(:message).once
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "FIXED"
+    Then the output should contain "1 example, 1 failure"
+    And the exit status should be 1
+
+  Scenario: Accessing `RSpec.configuration.mock_framework.framework_name`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :mocha
+      end
+
+      RSpec.describe "RSpec.configuration.mock_framework.framework_name" do
+        it "returns :mocha" do
+          expect(RSpec.configuration.mock_framework.framework_name).to eq(:mocha)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
diff --git a/rspec-core/features/mock_framework_integration/use_rr.feature b/rspec-core/features/mock_framework_integration/use_rr.feature
new file mode 100644
index 0000000..29d07ed
--- /dev/null
+++ b/rspec-core/features/mock_framework_integration/use_rr.feature
@@ -0,0 +1,96 @@
+Feature: mock with rr
+
+  Configure RSpec to use rr as shown in the scenarios below.
+
+  Scenario: Passing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rr
+      end
+
+      RSpec.describe "mocking with RSpec" do
+        it "passes when it should" do
+          receiver = Object.new
+          mock(receiver).message
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rr
+      end
+
+      RSpec.describe "mocking with RSpec" do
+        it "fails when it should" do
+          receiver = Object.new
+          mock(receiver).message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+
+  Scenario: Failing message expectation in pending example (remains pending)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rr
+      end
+
+      RSpec.describe "failed message expectation in a pending example" do
+        it "is listed as pending" do
+          pending
+          receiver = Object.new
+          mock(receiver).message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failures, 1 pending"
+    And the exit status should be 0
+
+  Scenario: Passing message expectation in pending example (fails)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rr
+      end
+
+      RSpec.describe "passing message expectation in a pending example" do
+        it "fails with FIXED" do
+          pending
+          receiver = Object.new
+          mock(receiver).message
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "FIXED"
+    Then the output should contain "1 example, 1 failure"
+    And the exit status should be 1
+
+  Scenario: Accessing `RSpec.configuration.mock_framework.framework_name`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rr
+      end
+
+      RSpec.describe "RSpec.configuration.mock_framework.framework_name" do
+        it "returns :rr" do
+          expect(RSpec.configuration.mock_framework.framework_name).to eq(:rr)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+
diff --git a/rspec-core/features/mock_framework_integration/use_rspec.feature b/rspec-core/features/mock_framework_integration/use_rspec.feature
new file mode 100644
index 0000000..9089acc
--- /dev/null
+++ b/rspec-core/features/mock_framework_integration/use_rspec.feature
@@ -0,0 +1,113 @@
+Feature: mock with rspec
+
+  RSpec uses its own mocking framework by default. You can also configure it
+  explicitly if you wish.
+
+  Scenario: Passing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rspec
+      end
+
+      RSpec.describe "mocking with RSpec" do
+        it "passes when it should" do
+          receiver = double('receiver')
+          expect(receiver).to receive(:message)
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failing message expectation
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rspec
+      end
+
+      RSpec.describe "mocking with RSpec" do
+        it "fails when it should" do
+          receiver = double('receiver')
+          expect(receiver).to receive(:message)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+
+  Scenario: Failing message expectation in pending example (remains pending)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rspec
+      end
+
+      RSpec.describe "failed message expectation in a pending example" do
+        it "is listed as pending" do
+          pending
+          receiver = double('receiver')
+          expect(receiver).to receive(:message)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "1 example, 0 failures, 1 pending"
+    And the exit status should be 0
+
+  Scenario: Passing message expectation in pending example (fails)
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rspec
+      end
+
+      RSpec.describe "passing message expectation in a pending example" do
+        it "fails with FIXED" do
+          pending
+          receiver = double('receiver')
+          expect(receiver).to receive(:message)
+          receiver.message
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain "FIXED"
+    Then the output should contain "1 example, 1 failure"
+    And the exit status should be 1
+
+  Scenario: Accessing `RSpec.configuration.mock_framework.framework_name`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rspec
+      end
+
+      RSpec.describe "RSpec.configuration.mock_framework.framework_name" do
+        it "returns :rspec" do
+          expect(RSpec.configuration.mock_framework.framework_name).to eq(:rspec)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Doubles may be used in generated descriptions
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_framework = :rspec
+      end
+
+      RSpec.describe "Testing" do
+        # Examples with no descriptions will default to RSpec-generated descriptions
+        it do
+          foo = double("Test")
+          expect(foo).to be foo
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/pending_and_skipped_examples/README.md b/rspec-core/features/pending_and_skipped_examples/README.md
new file mode 100644
index 0000000..be5c047
--- /dev/null
+++ b/rspec-core/features/pending_and_skipped_examples/README.md
@@ -0,0 +1,3 @@
+Sometimes you will have a failing example that can not be fixed, but is useful to keep around. For instance, the fix could depend on an upstream patch being merged, or the example is not supported on JRuby. RSpec provides two features for dealing with this scenario.
+
+An example can either be marked as _skipped_, in which is it not executed, or _pending_ in which it is executed but failure will not cause a failure of the entire suite. When a pending example passes (i.e. the underlying reasons for it being marked pending is no longer present) it will be marked as failed in order to communicate to you that it should no longer be marked as pending.
diff --git a/rspec-core/features/pending_and_skipped_examples/pending_examples.feature b/rspec-core/features/pending_and_skipped_examples/pending_examples.feature
new file mode 100644
index 0000000..7a5da21
--- /dev/null
+++ b/rspec-core/features/pending_and_skipped_examples/pending_examples.feature
@@ -0,0 +1,74 @@
+Feature: `pending` examples
+
+  RSpec offers a number of different ways to indicate that an example is
+  disabled pending some action.
+
+  Scenario: `pending` any arbitrary reason with a failing example
+    Given a file named "pending_without_block_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        it "is implemented but waiting" do
+          pending("something else getting finished")
+          fail
+        end
+      end
+      """
+    When I run `rspec pending_without_block_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) an example is implemented but waiting
+           # something else getting finished
+      """
+
+  Scenario: `pending` any arbitrary reason with a passing example
+    Given a file named "pending_with_passing_example_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        it "is implemented but waiting" do
+          pending("something else getting finished")
+          expect(1).to be(1)
+        end
+      end
+      """
+    When I run `rspec pending_with_passing_example_spec.rb`
+    Then the exit status should not be 0
+    And the output should contain "1 example, 1 failure"
+    And the output should contain "FIXED"
+    And the output should contain "Expected pending 'something else getting finished' to fail. No Error was raised."
+    And the output should contain "pending_with_passing_example_spec.rb:2"
+
+  Scenario: `pending` for an example that is currently passing
+    Given a file named "pending_with_passing_block_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        pending("something else getting finished") do
+          expect(1).to eq(1)
+        end
+      end
+      """
+    When I run `rspec pending_with_passing_block_spec.rb`
+    Then the exit status should not be 0
+    And the output should contain "1 example, 1 failure"
+    And the output should contain "FIXED"
+    And the output should contain "Expected pending 'No reason given' to fail. No Error was raised."
+    And the output should contain "pending_with_passing_block_spec.rb:2"
+
+  Scenario: `pending` for an example that is currently passing with a reason
+    Given a file named "pending_with_passing_block_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        example("something else getting finished", :pending => 'unimplemented') do
+          expect(1).to eq(1)
+        end
+      end
+      """
+    When I run `rspec pending_with_passing_block_spec.rb`
+    Then the exit status should not be 0
+    And the output should contain "1 example, 1 failure"
+    And the output should contain "FIXED"
+    And the output should contain "Expected pending 'unimplemented' to fail. No Error was raised."
+    And the output should contain "pending_with_passing_block_spec.rb:2"
diff --git a/rspec-core/features/pending_and_skipped_examples/skipped_examples.feature b/rspec-core/features/pending_and_skipped_examples/skipped_examples.feature
new file mode 100644
index 0000000..4ff3c82
--- /dev/null
+++ b/rspec-core/features/pending_and_skipped_examples/skipped_examples.feature
@@ -0,0 +1,112 @@
+Feature: `skip` examples
+
+  RSpec offers a number of ways to indicate that an example should be skipped
+  and not executed.
+
+  Scenario: No implementation provided
+    Given a file named "example_without_block_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        it "is a skipped example"
+      end
+      """
+    When I run `rspec example_without_block_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain "Not yet implemented"
+    And the output should contain "example_without_block_spec.rb:2"
+
+  Scenario: Skipping using `skip`
+    Given a file named "skipped_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        skip "is skipped" do
+        end
+      end
+      """
+    When I run `rspec skipped_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) an example is skipped
+           # No reason given
+           # ./skipped_spec.rb:2
+      """
+
+  Scenario: Skipping using `skip` inside an example
+    Given a file named "skipped_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        it "is skipped" do
+          skip
+        end
+      end
+      """
+    When I run `rspec skipped_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) an example is skipped
+           # No reason given
+           # ./skipped_spec.rb:2
+      """
+
+  Scenario: Temporarily skipping by prefixing `it`, `specify`, or `example` with an x
+    Given a file named "temporarily_skipped_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        xit "is skipped using xit" do
+        end
+
+        xspecify "is skipped using xspecify" do
+        end
+
+        xexample "is skipped using xexample" do
+        end
+      end
+      """
+    When I run `rspec temporarily_skipped_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "3 examples, 0 failures, 3 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) an example is skipped using xit
+           # Temporarily skipped with xit
+           # ./temporarily_skipped_spec.rb:2
+
+        2) an example is skipped using xspecify
+           # Temporarily skipped with xspecify
+           # ./temporarily_skipped_spec.rb:5
+
+        3) an example is skipped using xexample
+           # Temporarily skipped with xexample
+           # ./temporarily_skipped_spec.rb:8
+      """
+
+  Scenario: Skipping using metadata
+    Given a file named "skipped_spec.rb" with:
+      """ruby
+      RSpec.describe "an example" do
+        example "is skipped", :skip => true do
+        end
+      end
+      """
+    When I run `rspec skipped_spec.rb`
+    Then the exit status should be 0
+    And the output should contain "1 example, 0 failures, 1 pending"
+    And the output should contain:
+      """
+      Pending: (Failures listed here are expected and do not affect your suite's status)
+
+        1) an example is skipped
+           # No reason given
+           # ./skipped_spec.rb:2
+      """
diff --git a/rspec-core/features/spec_files/arbitrary_file_suffix.feature b/rspec-core/features/spec_files/arbitrary_file_suffix.feature
new file mode 100644
index 0000000..17921ef
--- /dev/null
+++ b/rspec-core/features/spec_files/arbitrary_file_suffix.feature
@@ -0,0 +1,13 @@
+Feature: arbitrary file suffix
+
+  Scenario: `.spec`
+    Given a file named "a.spec" with:
+      """ruby
+      RSpec.describe "something" do
+        it "does something" do
+          expect(3).to eq(3)
+        end
+      end
+      """
+    When I run `rspec a.spec`
+    Then the examples should all pass
diff --git a/rspec-core/features/step_definitions/additional_cli_steps.rb b/rspec-core/features/step_definitions/additional_cli_steps.rb
new file mode 100644
index 0000000..5ecfcad
--- /dev/null
+++ b/rspec-core/features/step_definitions/additional_cli_steps.rb
@@ -0,0 +1,126 @@
+require 'rspec/core'  # to fix annoying "undefined method `configuration' for RSpec:Module (NoMethodError)"
+
+Then /^the output should contain all of these:$/ do |table|
+  table.raw.flatten.each do |string|
+    assert_partial_output(string, all_output)
+  end
+end
+
+Then /^the output should not contain any of these:$/ do |table|
+  table.raw.flatten.each do |string|
+    expect(all_output).not_to include(string)
+  end
+end
+
+Then /^the output should contain one of the following:$/ do |table|
+  matching_output = table.raw.flatten.select do |string|
+    all_output.include?(string)
+  end
+
+  expect(matching_output.count).to eq(1)
+end
+
+Then /^the example(?:s)? should(?: all)? pass$/ do
+  step %q{the output should contain "0 failures"}
+  step %q{the output should not contain "0 examples"}
+  step %q{the exit status should be 0}
+end
+
+Then /^the example(?:s)? should(?: all)? fail$/ do
+  step %q{the output should not contain "0 examples"}
+  step %q{the output should not contain "0 failures"}
+  step %q{the exit status should be 1}
+  example_summary = /(\d+) examples?, (\d+) failures?/.match(all_output)
+  example_count, failure_count = example_summary.captures
+  expect(failure_count).to eq(example_count)
+end
+
+Then /^the process should succeed even though no examples were run$/ do
+  step %q{the output should contain "0 examples, 0 failures"}
+  step %q{the exit status should be 0}
+end
+
+addition_example_formatter_output = <<-EOS
+Addition
+  works
+EOS
+
+Then /^the output from `([^`]+)` (should(?: not)?) be in documentation format$/ do |cmd, should_or_not|
+  step %Q{I run `#{cmd}`}
+  step %q{the examples should all pass}
+  step %Q{the output from "#{cmd}" #{should_or_not} contain "#{addition_example_formatter_output}"}
+end
+
+Then(/^the output from `([^`]+)` should indicate it ran only the subtraction file$/) do |cmd|
+  step %Q{I run `#{cmd}`}
+  step %q{the examples should all pass}
+  step %Q{the output from "#{cmd}" should contain "1 example, 0 failures"}
+  step %Q{the output from "#{cmd}" should contain "Subtraction"}
+  step %Q{the output from "#{cmd}" should not contain "Addition"}
+end
+
+Then /^the backtrace\-normalized output should contain:$/ do |partial_output|
+  # ruby 1.9 includes additional stuff in the backtrace,
+  # so we need to normalize it to compare it with our expected output.
+  normalized_output = all_output.split("\n").map do |line|
+    line =~ /(^\s+# [^:]+:\d+)/ ? $1 : line # http://rubular.com/r/zDD7DdWyzF
+  end.join("\n")
+
+  expect(normalized_output).to include(partial_output)
+end
+
+Then /^the output should not contain any error backtraces$/ do
+  step %q{the output should not contain "lib/rspec/core"}
+end
+
+# This step can be generalized if it's ever used to test other colors
+Then /^the failing example is printed in magenta$/ do
+  # \e[35m = enable magenta
+  # \e[0m  = reset colors
+  expect(all_output).to include("\e[35m" + "F" + "\e[0m")
+end
+
+Then /^the output from `([^`]+)` should contain "(.*?)"$/  do |cmd, expected_output|
+  step %Q{I run `#{cmd}`}
+  step %Q{the output from "#{cmd}" should contain "#{expected_output}"}
+end
+
+Then /^the output from `([^`]+)` should not contain "(.*?)"$/  do |cmd, expected_output|
+  step %Q{I run `#{cmd}`}
+  step %Q{the output from "#{cmd}" should not contain "#{expected_output}"}
+end
+
+Given /^I have a brand new project with no files$/ do
+  in_current_dir do
+    expect(Dir["**/*"]).to eq([])
+  end
+end
+
+Given /^I have run `([^`]*)`$/ do |cmd|
+  fail_on_error = true
+  run_simple(unescape(cmd), fail_on_error)
+end
+
+Given(/^a vendored gem named "(.*?)" containing a file named "(.*?)" with:$/) do |gem_name, file_name, file_contents|
+  gem_dir = "vendor/#{gem_name}-1.2.3"
+  step %Q{a file named "#{gem_dir}/#{file_name}" with:}, file_contents
+  set_env('RUBYOPT', ENV['RUBYOPT'] + " -I#{gem_dir}/lib")
+end
+
+When "I accept the recommended settings by removing `=begin` and `=end` from `spec/spec_helper.rb`" do
+  in_current_dir do
+    spec_helper = File.read("spec/spec_helper.rb")
+    expect(spec_helper).to include("=begin", "=end")
+
+    to_keep = spec_helper.lines.reject do |line|
+      line.start_with?("=begin") || line.start_with?("=end")
+    end
+
+    File.open("spec/spec_helper.rb", "w") { |f| f.write(to_keep.join) }
+    expect(File.read("spec/spec_helper.rb")).not_to include("=begin", "=end")
+  end
+end
+
+When /^I create "([^"]*)" with the following content:$/ do |file_name, content|
+  write_file(file_name, content)
+end
diff --git a/rspec-core/features/step_definitions/core_standalone_steps.rb b/rspec-core/features/step_definitions/core_standalone_steps.rb
new file mode 100644
index 0000000..fd24c3a
--- /dev/null
+++ b/rspec-core/features/step_definitions/core_standalone_steps.rb
@@ -0,0 +1,12 @@
+Given(/^only rspec-core is installed$/) do
+  if RUBY_VERSION.to_f >= 1.9 # --disable-gems is invalid on 1.8.7
+    # Ensure the gem versions of rspec-mocks and rspec-expectations
+    # won't be loaded if available on the developers machine.
+    set_env('RUBYOPT', ENV['RUBYOPT'] + ' --disable-gems')
+  end
+
+  # This will make `require_expect_syntax_in_aruba_specs.rb` (loaded
+  # automatically when the specs run) remove rspec-mocks and
+  # rspec-expectations from the load path.
+  set_env('REMOVE_OTHER_RSPEC_LIBS_FROM_LOAD_PATH', 'true')
+end
diff --git a/rspec-core/features/subject/explicit_subject.feature b/rspec-core/features/subject/explicit_subject.feature
new file mode 100644
index 0000000..af64e25
--- /dev/null
+++ b/rspec-core/features/subject/explicit_subject.feature
@@ -0,0 +1,187 @@
+Feature: Explicit Subject
+
+  Use `subject` in the group scope to explicitly define the value that is returned by the
+  `subject` method in the example scope.
+
+  Note that while the examples below demonstrate how the `subject` helper can be used
+  as a user-facing concept, we recommend that you reserve it for support of custom
+  matchers and/or extension libraries that hide its use from examples.
+
+  A named `subject` improves on the explicit `subject` by assigning it a contextually
+  semantic name. Since a named `subject` is an explicit `subject`, it still defines the value
+  that is returned by the `subject` method in the example scope. However, it defines an
+  additional helper method with the provided name. This helper method is memoized.
+  The value is cached across multiple calls in the same example but not across examples.
+
+  We recommend using the named helper method over `subject` in examples.
+
+  For more information about declaring a `subject` see the [API docs](http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/MemoizedHelpers/ClassMethods#subject-instance_method).
+
+  Scenario: A `subject` can be defined and used in the top level group scope
+    Given a file named "top_level_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array, "with some elements" do
+        subject { [1, 2, 3] }
+
+        it "has the prescribed elements" do
+          expect(subject).to eq([1, 2, 3])
+        end
+      end
+      """
+    When I run `rspec top_level_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: The `subject` defined in an outer group is available to inner groups
+    Given a file named "nested_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        subject { [1, 2, 3] }
+
+        describe "has some elements" do
+          it "which are the prescribed elements" do
+            expect(subject).to eq([1, 2, 3])
+          end
+        end
+      end
+      """
+    When I run `rspec nested_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: The `subject` is memoized within an example but not across examples
+    **Note:** This scenario shows mutation being performed in a `subject` definition block. This
+    behavior is generally discouraged as it makes it more difficult to understand the specs.
+    This is technique is used simply as a tool to demonstrate how the memoization occurs.
+    Given a file named "memoized_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        # This uses a context local variable. As you can see from the
+        # specs, it can mutate across examples. Use with caution.
+        element_list = [1, 2, 3]
+
+        subject { element_list.pop }
+
+        it "is memoized across calls (i.e. the block is invoked once)" do
+          expect {
+            3.times { subject }
+          }.to change{ element_list }.from([1, 2, 3]).to([1, 2])
+          expect(subject).to eq(3)
+        end
+
+        it "is not memoized across examples" do
+          expect{ subject }.to change{ element_list }.from([1, 2]).to([1])
+          expect(subject).to eq(2)
+        end
+      end
+      """
+    When I run `rspec memoized_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: The `subject` is available in `before` hooks
+    Given a file named "before_hook_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array, "with some elements" do
+        subject { [] }
+
+        before { subject.push(1, 2, 3) }
+
+        it "has the prescribed elements" do
+          expect(subject).to eq([1, 2, 3])
+        end
+      end
+      """
+    When I run `rspec before_hook_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Helper methods can be invoked from a `subject` definition block
+    Given a file named "helper_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array, "with some elements" do
+        def prepared_array
+          [1, 2, 3]
+        end
+
+        subject { prepared_array }
+
+        it "has the prescribed elements" do
+          expect(subject).to eq([1, 2, 3])
+        end
+      end
+      """
+    When I run `rspec helper_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use the `subject!` bang method to call the definition block before the example
+    Given a file named "subject_bang_spec.rb" with:
+      """ruby
+      RSpec.describe "eager loading with subject!" do
+        subject! { element_list.push(99) }
+
+        let(:element_list) { [1, 2, 3] }
+
+        it "calls the definition block before the example" do
+          element_list.push(5)
+          expect(element_list).to eq([1, 2, 3, 99, 5])
+        end
+      end
+      """
+    When I run `rspec subject_bang_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `subject(:name)` to define a memoized helper method
+    **Note:** While a global variable is used in the examples below, this behavior is strongly
+    discouraged in actual specs. It is used here simply to demonstrate the value will be
+    cached across multiple calls in the same example but not across examples.
+    Given a file named "named_subject_spec.rb" with:
+      """ruby
+      $count = 0
+
+      RSpec.describe "named subject" do
+        subject(:global_count) { $count += 1 }
+
+        it "is memoized across calls (i.e. the block is invoked once)" do
+          expect {
+            2.times { global_count }
+          }.not_to change{ global_count }.from(1)
+        end
+
+        it "is not cached across examples" do
+          expect(global_count).to eq(2)
+        end
+
+        it "is still available using the subject method" do
+          expect(subject).to eq(3)
+        end
+
+        it "works with the one-liner syntax" do
+          is_expected.to eq(4)
+        end
+
+        it "the subject and named helpers return the same object" do
+          expect(global_count).to be(subject)
+        end
+
+        it "is set to the block return value (i.e. the global $count)" do
+          expect(global_count).to be($count)
+        end
+      end
+      """
+    When I run `rspec named_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `subject!(:name)` to define a helper method called before the example
+    Given a file named "named_subject_bang_spec.rb" with:
+      """ruby
+      RSpec.describe "eager loading using a named subject!" do
+        subject!(:updated_list) { element_list.push(99) }
+
+        let(:element_list) { [1, 2, 3] }
+
+        it "calls the definition block before the example" do
+          element_list.push(5)
+          expect(element_list).to eq([1, 2, 3, 99, 5])
+          expect(updated_list).to be(element_list)
+        end
+      end
+      """
+    When I run `rspec named_subject_bang_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/subject/implicit_subject.feature b/rspec-core/features/subject/implicit_subject.feature
new file mode 100644
index 0000000..2d46929
--- /dev/null
+++ b/rspec-core/features/subject/implicit_subject.feature
@@ -0,0 +1,57 @@
+Feature: implicitly defined subject
+
+  If the first argument to the outermost example group is a class, an instance
+  of that class is exposed to each example via the `subject` method.
+
+  While the examples below demonstrate how `subject` can be used as a
+  user-facing concept, we recommend that you reserve it for support of custom
+  matchers and/or extension libraries that hide its use from examples.
+
+  Scenario: `subject` exposed in top level group
+    Given a file named "top_level_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        it "should be empty when first created" do
+          expect(subject).to be_empty
+        end
+      end
+      """
+    When I run `rspec ./top_level_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `subject` in a nested group
+    Given a file named "nested_subject_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        describe "when first created" do
+          it "should be empty" do
+            expect(subject).to be_empty
+          end
+        end
+      end
+      """
+    When I run `rspec nested_subject_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `subject` in a nested group with a different class (innermost wins)
+    Given a file named "nested_subject_spec.rb" with:
+      """ruby
+      class ArrayWithOneElement < Array
+        def initialize(*)
+          super
+          unshift "first element"
+        end
+      end
+
+      RSpec.describe Array do
+        describe ArrayWithOneElement do
+          context "referenced as subject" do
+            it "contains one element" do
+              expect(subject).to include("first element")
+            end
+          end
+        end
+      end
+      """
+    When I run `rspec nested_subject_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-core/features/subject/one_liner_syntax.feature b/rspec-core/features/subject/one_liner_syntax.feature
new file mode 100644
index 0000000..07860fd
--- /dev/null
+++ b/rspec-core/features/subject/one_liner_syntax.feature
@@ -0,0 +1,72 @@
+ at oneliner-should
+Feature: One-liner syntax
+
+  RSpec supports a one-liner syntax for setting an expectation on the
+  `subject`.  RSpec will give the examples a doc string that is auto-
+  generated from the matcher used in the example. This is designed specifically
+  to help avoid duplication in situations where the doc string and the matcher
+  used in the example mirror each other exactly. When used excessively, it can
+  produce documentation output that does not read well or contribute to
+  understanding the object you are describing.
+
+  This comes in two flavors:
+
+    * `is_expected` is defined simply as `expect(subject)` and is designed for
+      when you are using rspec-expectations with its newer expect-based syntax.
+    * `should` was designed back when rspec-expectations only had a should-based
+      syntax. However, it continues to be available and work even if the
+      `:should` syntax is disabled (since that merely removes `Object#should`
+      but this is `RSpec::Core::ExampleGroup#should`).
+
+  Notes:
+
+    * This feature is only available when using rspec-expectations.
+    * Examples defined using this one-liner syntax cannot be directly selected from the command line using the [`--example` option](../command-line/example-option).
+
+  Scenario: Implicit subject
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        describe "when first created" do
+          # Rather than:
+          # it "should be empty" do
+          #   subject.should be_empty
+          # end
+
+          it { should be_empty }
+          # or
+          it { is_expected.to be_empty }
+        end
+      end
+      """
+    When I run `rspec example_spec.rb --format doc`
+    Then the examples should all pass
+     And the output should contain:
+       """
+       Array
+         when first created
+           should be empty
+           should be empty
+       """
+
+  Scenario: Explicit subject
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        describe "with 3 items" do
+          subject { [1,2,3] }
+          it { should_not be_empty }
+          # or
+          it { is_expected.not_to be_empty }
+        end
+      end
+      """
+    When I run `rspec example_spec.rb --format doc`
+    Then the examples should all pass
+     And the output should contain:
+       """
+       Array
+         with 3 items
+           should not be empty
+           should not be empty
+       """
diff --git a/rspec-core/features/support/env.rb b/rspec-core/features/support/env.rb
new file mode 100644
index 0000000..36b8026
--- /dev/null
+++ b/rspec-core/features/support/env.rb
@@ -0,0 +1,21 @@
+require 'aruba/cucumber'
+
+Before do
+  if RUBY_PLATFORM =~ /java/ || defined?(Rubinius)
+    @aruba_timeout_seconds = 60
+  else
+    @aruba_timeout_seconds = 10
+  end
+end
+
+Aruba.configure do |config|
+  config.before_cmd do |cmd|
+    set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
+  end
+end if RUBY_PLATFORM == 'java'
+
+Aruba.configure do |config|
+  config.before_cmd do |cmd|
+    set_env('RBXOPT', "-Xint=true #{ENV['RBXOPT']}") # disable JIT since these processes are so short lived
+  end
+end if defined?(Rubinius)
diff --git a/rspec-core/features/support/require_expect_syntax_in_aruba_specs.rb b/rspec-core/features/support/require_expect_syntax_in_aruba_specs.rb
new file mode 100644
index 0000000..191998e
--- /dev/null
+++ b/rspec-core/features/support/require_expect_syntax_in_aruba_specs.rb
@@ -0,0 +1,29 @@
+if defined?(Cucumber)
+  require 'shellwords'
+  Before('~@allow-should-syntax') do
+    set_env('SPEC_OPTS', "-r#{Shellwords.escape(__FILE__)}")
+  end
+
+  Before('@oneliner-should') do
+    set_env('ALLOW_ONELINER_SHOULD', 'true')
+  end
+else
+  if ENV['REMOVE_OTHER_RSPEC_LIBS_FROM_LOAD_PATH']
+    $LOAD_PATH.reject! { |x| /rspec-mocks/ === x || /rspec-expectations/ === x }
+  end
+
+  module DisallowOneLinerShould
+    def should(*)
+      raise "one-liner should is not allowed"
+    end
+
+    def should_not(*)
+      raise "one-liner should_not is not allowed"
+    end
+  end
+
+  RSpec.configure do |rspec|
+    rspec.disable_monkey_patching!
+    rspec.include DisallowOneLinerShould unless ENV['ALLOW_ONELINER_SHOULD']
+  end
+end
diff --git a/rspec-core/features/support/rubinius.rb b/rspec-core/features/support/rubinius.rb
new file mode 100644
index 0000000..3907962
--- /dev/null
+++ b/rspec-core/features/support/rubinius.rb
@@ -0,0 +1,6 @@
+# Required until https://github.com/rubinius/rubinius/issues/2430 is resolved
+ENV['RBXOPT'] = "#{ENV["RBXOPT"]} -Xcompiler.no_rbc"
+
+Around "@unsupported-on-rbx" do |scenario, block|
+  block.call unless defined?(Rubinius)
+end
diff --git a/rspec-core/lib/rspec/autorun.rb b/rspec-core/lib/rspec/autorun.rb
new file mode 100644
index 0000000..18cc1ed
--- /dev/null
+++ b/rspec-core/lib/rspec/autorun.rb
@@ -0,0 +1,2 @@
+require 'rspec/core'
+RSpec::Core::Runner.autorun
diff --git a/rspec-core/lib/rspec/core.rb b/rspec-core/lib/rspec/core.rb
new file mode 100644
index 0000000..77d9370
--- /dev/null
+++ b/rspec-core/lib/rspec/core.rb
@@ -0,0 +1,189 @@
+# rubocop:disable Style/GlobalVars
+$_rspec_core_load_started_at = Time.now
+# rubocop:enable Style/GlobalVars
+
+require 'rbconfig'
+
+require "rspec/support"
+RSpec::Support.require_rspec_support "caller_filter"
+
+RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative f }
+
+%w[
+  version
+  warnings
+
+  flat_map
+  filter_manager
+  dsl
+  notifications
+  reporter
+
+  hooks
+  memoized_helpers
+  metadata
+  metadata_filter
+  pending
+  formatters
+  ordering
+
+  world
+  configuration
+  option_parser
+  configuration_options
+  runner
+  example
+  shared_example_group
+  example_group
+].each { |name| RSpec::Support.require_rspec_core name }
+
+# Namespace for all core RSpec code.
+module RSpec
+  autoload :SharedContext, 'rspec/core/shared_context'
+
+  extend RSpec::Core::Warnings
+
+  class << self
+    # Setters for shared global objects
+    # @api private
+    attr_writer :configuration, :world
+  end
+
+  # Used to ensure examples get reloaded and user configuration gets reset to
+  # defaults between multiple runs in the same process.
+  #
+  # Users must invoke this if they want to have the configuration reset when
+  # they use the runner multiple times within the same process. Users must deal
+  # themselves with re-configuration of RSpec before run.
+  def self.reset
+    @world = nil
+    @configuration = nil
+  end
+
+  # Used to ensure examples get reloaded between multiple runs in the same
+  # process and ensures user configuration is persisted.
+  #
+  # Users must invoke this if they want to clear all examples but preserve
+  # current configuration when they use the runner multiple times within the
+  # same process.
+  def self.clear_examples
+    world.reset
+    configuration.reporter.reset
+    configuration.start_time = ::RSpec::Core::Time.now
+    configuration.reset_filters
+  end
+
+  # Returns the global [Configuration](RSpec/Core/Configuration) object. While
+  # you _can_ use this method to access the configuration, the more common
+  # convention is to use [RSpec.configure](RSpec#configure-class_method).
+  #
+  # @example
+  #     RSpec.configuration.drb_port = 1234
+  # @see RSpec.configure
+  # @see Core::Configuration
+  def self.configuration
+    @configuration ||= begin
+                         config = RSpec::Core::Configuration.new
+                         config.expose_dsl_globally = true
+                         config
+                       end
+  end
+
+  # Yields the global configuration to a block.
+  # @yield [Configuration] global configuration
+  #
+  # @example
+  #     RSpec.configure do |config|
+  #       config.add_formatter 'documentation'
+  #     end
+  # @see Core::Configuration
+  def self.configure
+    yield configuration if block_given?
+  end
+
+  # The example being executed.
+  #
+  # The primary audience for this method is library authors who need access
+  # to the example currently being executed and also want to support all
+  # versions of RSpec 2 and 3.
+  #
+  # @example
+  #
+  #     RSpec.configure do |c|
+  #       # context.example is deprecated, but RSpec.current_example is not
+  #       # available until RSpec 3.0.
+  #       fetch_current_example = RSpec.respond_to?(:current_example) ?
+  #         proc { RSpec.current_example } : proc { |context| context.example }
+  #
+  #       c.before(:example) do
+  #         example = fetch_current_example.call(self)
+  #
+  #         # ...
+  #       end
+  #     end
+  #
+  def self.current_example
+    thread_local_metadata[:current_example]
+  end
+
+  # Set the current example being executed.
+  # @api private
+  def self.current_example=(example)
+    thread_local_metadata[:current_example] = example
+  end
+
+  # @private
+  # A single thread local variable so we don't excessively pollute that
+  # namespace.
+  def self.thread_local_metadata
+    Thread.current[:_rspec] ||= { :shared_example_group_inclusions => [] }
+  end
+
+  # @private
+  # Internal container for global non-configuration data.
+  def self.world
+    @world ||= RSpec::Core::World.new
+  end
+
+  # Namespace for the rspec-core code.
+  module Core
+    # @private
+    # This avoids issues with reporting time caused by examples that
+    # change the value/meaning of Time.now without properly restoring
+    # it.
+    class Time
+      class << self
+        define_method(:now, &::Time.method(:now))
+      end
+    end
+
+    # @private path to executable file.
+    def self.path_to_executable
+      @path_to_executable ||= File.expand_path('../../../exe/rspec', __FILE__)
+    end
+  end
+
+  # @private
+  MODULES_TO_AUTOLOAD = {
+    :Matchers     => "rspec/expectations",
+    :Expectations => "rspec/expectations",
+    :Mocks        => "rspec/mocks"
+  }
+
+  # @private
+  def self.const_missing(name)
+    # Load rspec-expectations when RSpec::Matchers is referenced. This allows
+    # people to define custom matchers (using `RSpec::Matchers.define`) before
+    # rspec-core has loaded rspec-expectations (since it delays the loading of
+    # it to allow users to configure a different assertion/expectation
+    # framework). `autoload` can't be used since it works with ruby's built-in
+    # require (e.g. for files that are available relative to a load path dir),
+    # but not with rubygems' extended require.
+    #
+    # As of rspec 2.14.1, we no longer require `rspec/mocks` and
+    # `rspec/expectations` when `rspec` is required, so we want
+    # to make them available as an autoload.
+    require MODULES_TO_AUTOLOAD.fetch(name) { return super }
+    ::RSpec.const_get(name)
+  end
+end
diff --git a/rspec-core/lib/rspec/core/backport_random.rb b/rspec-core/lib/rspec/core/backport_random.rb
new file mode 100644
index 0000000..1b8afaf
--- /dev/null
+++ b/rspec-core/lib/rspec/core/backport_random.rb
@@ -0,0 +1,339 @@
+module RSpec
+  module Core
+    # @private
+    #
+    # Methods used internally by the backports.
+    #
+    # This code was (mostly) ported from the backports gem found at
+    # https://github.com/marcandre/backports which is subject to this license:
+    #
+    # =========================================================================
+    #
+    # Copyright (c) 2009 Marc-Andre Lafortune
+    #
+    # 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.
+    #
+    # =========================================================================
+    #
+    # The goal is to provide a random number generator in Ruby versions that do
+    # not have one. This was added to support localization of random spec
+    # ordering.
+    #
+    # These were in multiple files in backports, but merged into one here.
+    module Backports
+      # Helper method to coerce a value into a specific class.
+      # Raises a TypeError if the coercion fails or the returned value
+      # is not of the right class.
+      # (from Rubinius)
+      def self.coerce_to(obj, cls, meth)
+        return obj if obj.kind_of?(cls)
+
+        begin
+          ret = obj.__send__(meth)
+        rescue Exception => e
+          raise TypeError, "Coercion error: #{obj.inspect}.#{meth} => #{cls} failed:\n" \
+                           "(#{e.message})"
+        end
+        raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{ret.class})" unless ret.kind_of? cls
+        ret
+      end
+
+      # @private
+      def self.coerce_to_int(obj)
+        coerce_to(obj, Integer, :to_int)
+      end
+
+      # Used internally to make it easy to deal with optional arguments.
+      # (from Rubinius)
+      Undefined = Object.new
+
+      # @private
+      class Random
+        # @private
+        # An implementation of Mersenne Twister MT19937 in Ruby.
+        class MT19937
+          STATE_SIZE = 624
+          LAST_STATE = STATE_SIZE - 1
+          PAD_32_BITS = 0xffffffff
+
+          # See seed=
+          def initialize(seed)
+            self.seed = seed
+          end
+
+          LAST_31_BITS = 0x7fffffff
+          OFFSET = 397
+
+          # Generates a completely new state out of the previous one.
+          def next_state
+            STATE_SIZE.times do |i|
+              mix = @state[i] & 0x80000000 | @state[i+1 - STATE_SIZE] & 0x7fffffff
+              @state[i] = @state[i+OFFSET - STATE_SIZE] ^ (mix >> 1)
+              @state[i] ^= 0x9908b0df if mix.odd?
+            end
+            @last_read = -1
+          end
+
+          # Seed must be either an Integer (only the first 32 bits will be used)
+          # or an Array of Integers (of which only the first 32 bits will be
+          # used).
+          #
+          # No conversion or type checking is done at this level.
+          def seed=(seed)
+            case seed
+            when Integer
+              @state = Array.new(STATE_SIZE)
+              @state[0] = seed & PAD_32_BITS
+              (1..LAST_STATE).each do |i|
+                @state[i] = (1812433253 * (@state[i-1]  ^ @state[i-1]>>30) + i)& PAD_32_BITS
+              end
+              @last_read = LAST_STATE
+            when Array
+              self.seed = 19650218
+              i=1
+              j=0
+              [STATE_SIZE, seed.size].max.times do
+                @state[i] = (@state[i] ^ (@state[i-1] ^ @state[i-1]>>30) * 1664525) + j + seed[j] & PAD_32_BITS
+                if (i+=1) >= STATE_SIZE
+                  @state[0] = @state[-1]
+                  i = 1
+                end
+                j = 0 if (j+=1) >= seed.size
+              end
+              (STATE_SIZE-1).times do
+                @state[i] = (@state[i] ^ (@state[i-1] ^ @state[i-1]>>30) * 1566083941) - i & PAD_32_BITS
+                if (i+=1) >= STATE_SIZE
+                  @state[0] = @state[-1]
+                  i = 1
+                end
+              end
+              @state[0] = 0x80000000
+            else
+              raise ArgumentError, "Seed must be an Integer or an Array"
+            end
+          end
+
+          # Returns a random Integer from the range 0 ... (1 << 32).
+          def random_32_bits
+            next_state if @last_read >= LAST_STATE
+            @last_read += 1
+            y = @state[@last_read]
+            # Tempering
+            y ^= (y >> 11)
+            y ^= (y << 7) & 0x9d2c5680
+            y ^= (y << 15) & 0xefc60000
+            y ^= (y >> 18)
+          end
+
+          # Supplement the MT19937 class with methods to do
+          # conversions the same way as MRI.
+          # No argument checking is done here either.
+
+          FLOAT_FACTOR = 1.0/9007199254740992.0
+          # Generates a random number on [0, 1) with 53-bit resolution.
+          def random_float
+            ((random_32_bits >> 5) * 67108864.0 + (random_32_bits >> 6)) * FLOAT_FACTOR;
+          end
+
+          # Returns an integer within 0...upto.
+          def random_integer(upto)
+            n = upto - 1
+            nb_full_32 = 0
+            while n > PAD_32_BITS
+              n >>= 32
+              nb_full_32 += 1
+            end
+            mask = mask_32_bits(n)
+            begin
+              rand = random_32_bits & mask
+              nb_full_32.times do
+                rand <<= 32
+                rand |= random_32_bits
+              end
+            end until rand < upto
+            rand
+          end
+
+          def random_bytes(nb)
+            nb_32_bits = (nb + 3) / 4
+            random = nb_32_bits.times.map { random_32_bits }
+            random.pack("L" * nb_32_bits)[0, nb]
+          end
+
+          def state_as_bignum
+            b = 0
+            @state.each_with_index do |val, i|
+              b |= val << (32 * i)
+            end
+            b
+          end
+
+          def left # It's actually the number of words left + 1, as per MRI...
+            MT19937::STATE_SIZE - @last_read
+          end
+
+          def marshal_dump
+            [state_as_bignum, left]
+          end
+
+          def marshal_load(ary)
+            b, left = ary
+            @last_read = MT19937::STATE_SIZE - left
+            @state = Array.new(STATE_SIZE)
+            STATE_SIZE.times do |i|
+              @state[i] = b & PAD_32_BITS
+              b >>= 32
+            end
+          end
+
+          # Convert an Integer seed of arbitrary size to either a single 32 bit
+          # integer, or an Array of 32 bit integers.
+          def self.convert_seed(seed)
+            seed = seed.abs
+            long_values = []
+            begin
+              long_values << (seed & PAD_32_BITS)
+              seed >>= 32
+            end until seed == 0
+
+            # Done to allow any kind of sequence of integers.
+            long_values.pop if long_values[-1] == 1 && long_values.size > 1
+
+            long_values.size > 1 ? long_values : long_values.first
+          end
+
+          def self.[](seed)
+            new(convert_seed(seed))
+          end
+
+          private
+
+          MASK_BY = [1,2,4,8,16]
+          def mask_32_bits(n)
+            MASK_BY.each do |shift|
+              n |= n >> shift
+            end
+            n
+          end
+        end
+
+        # @private
+        # Implementation corresponding to the actual Random class of Ruby
+        # The actual random generator (mersenne twister) is in MT19937.
+        # Ruby specific conversions are handled in bits_and_bytes.
+        # The high level stuff (argument checking) is done here.
+        module Implementation
+          attr_reader :seed
+
+          def initialize(seed = 0)
+            super()
+            seed_rand seed
+          end
+
+          def seed_rand(new_seed = 0)
+            new_seed = Backports.coerce_to_int(new_seed)
+            @seed = nil unless defined?(@seed)
+            old, @seed = @seed, new_seed.nonzero? || Random.new_seed
+            @mt = MT19937[ @seed ]
+            old
+          end
+
+          def rand(limit = Backports::Undefined)
+            case limit
+              when Backports::Undefined
+                @mt.random_float
+              when Float
+                limit * @mt.random_float unless limit <= 0
+              when Range
+                _rand_range(limit)
+              else
+                limit = Backports.coerce_to_int(limit)
+                @mt.random_integer(limit) unless limit <= 0
+            end || raise(ArgumentError, "invalid argument #{limit}")
+          end
+
+          def bytes(nb)
+            nb = Backports.coerce_to_int(nb)
+            raise ArgumentError, "negative size" if nb < 0
+            @mt.random_bytes(nb)
+          end
+
+          def ==(other)
+            other.is_a?(Random) &&
+              seed == other.seed &&
+              left == other.send(:left) &&
+              state == other.send(:state)
+          end
+
+          def marshal_dump
+            @mt.marshal_dump << @seed
+          end
+
+          def marshal_load(ary)
+            @seed = ary.pop
+            @mt = MT19937.allocate
+            @mt.marshal_load(ary)
+          end
+
+          private
+
+          def state
+            @mt.state_as_bignum
+          end
+
+          def left
+            @mt.left
+          end
+
+          def _rand_range(limit)
+            range = limit.end - limit.begin
+            if (!range.is_a?(Float)) && range.respond_to?(:to_int) && range = Backports.coerce_to_int(range)
+              range += 1 unless limit.exclude_end?
+              limit.begin + @mt.random_integer(range) unless range <= 0
+            elsif range = Backports.coerce_to(range, Float, :to_f)
+              if range < 0
+                nil
+              elsif limit.exclude_end?
+                limit.begin + @mt.random_float * range unless range <= 0
+              else
+                # cheat a bit... this will reduce the nb of random bits
+                loop do
+                  r = @mt.random_float * range * 1.0001
+                  break limit.begin + r unless r > range
+                end
+              end
+            end
+          end
+        end
+
+        def self.new_seed
+          (2 ** 62) + Kernel.rand(2 ** 62)
+        end
+      end
+
+      class Random
+        include Implementation
+        class << self
+          include Implementation
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/backtrace_formatter.rb b/rspec-core/lib/rspec/core/backtrace_formatter.rb
new file mode 100644
index 0000000..b1dff2f
--- /dev/null
+++ b/rspec-core/lib/rspec/core/backtrace_formatter.rb
@@ -0,0 +1,66 @@
+module RSpec
+  module Core
+    # @private
+    class BacktraceFormatter
+      # @private
+      attr_accessor :exclusion_patterns, :inclusion_patterns
+
+      def initialize
+        @full_backtrace = false
+
+        patterns = %w[ /lib\d*/ruby/ bin/ exe/rspec ]
+        patterns << "org/jruby/" if RUBY_PLATFORM == 'java'
+        patterns.map! { |s| Regexp.new(s.gsub("/", File::SEPARATOR)) }
+
+        @exclusion_patterns = [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *patterns)]
+        @inclusion_patterns = []
+
+        return unless matches?(@exclusion_patterns, File.join(Dir.getwd, "lib", "foo.rb:13"))
+        inclusion_patterns << Regexp.new(Dir.getwd)
+      end
+
+      attr_writer :full_backtrace
+
+      def full_backtrace?
+        @full_backtrace || exclusion_patterns.empty?
+      end
+
+      def filter_gem(gem_name)
+        sep = File::SEPARATOR
+        exclusion_patterns << /#{sep}#{gem_name}(-[^#{sep}]+)?#{sep}/
+      end
+
+      def format_backtrace(backtrace, options={})
+        return backtrace if options[:full_backtrace]
+
+        backtrace.map { |l| backtrace_line(l) }.compact.
+          tap do |filtered|
+            if filtered.empty?
+              filtered.concat backtrace
+              filtered << ""
+              filtered << "  Showing full backtrace because every line was filtered out."
+              filtered << "  See docs for RSpec::Configuration#backtrace_exclusion_patterns and"
+              filtered << "  RSpec::Configuration#backtrace_inclusion_patterns for more information."
+            end
+          end
+      end
+
+      def backtrace_line(line)
+        Metadata.relative_path(line) unless exclude?(line)
+      rescue SecurityError
+        nil
+      end
+
+      def exclude?(line)
+        return false if @full_backtrace
+        matches?(exclusion_patterns, line) && !matches?(inclusion_patterns, line)
+      end
+
+    private
+
+      def matches?(patterns, line)
+        patterns.any? { |p| line =~ p }
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/configuration.rb b/rspec-core/lib/rspec/core/configuration.rb
new file mode 100644
index 0000000..f5dd8f9
--- /dev/null
+++ b/rspec-core/lib/rspec/core/configuration.rb
@@ -0,0 +1,1678 @@
+RSpec::Support.require_rspec_core "backtrace_formatter"
+RSpec::Support.require_rspec_core "ruby_project"
+RSpec::Support.require_rspec_core "formatters/deprecation_formatter"
+
+module RSpec
+  module Core
+    # rubocop:disable Style/ClassLength
+
+    # Stores runtime configuration information.
+    #
+    # Configuration options are loaded from `~/.rspec`, `.rspec`,
+    # `.rspec-local`, command line switches, and the `SPEC_OPTS` environment
+    # variable (listed in lowest to highest precedence; for example, an option
+    # in `~/.rspec` can be overridden by an option in `.rspec-local`).
+    #
+    # @example Standard settings
+    #     RSpec.configure do |c|
+    #       c.drb          = true
+    #       c.drb_port     = 1234
+    #       c.default_path = 'behavior'
+    #     end
+    #
+    # @example Hooks
+    #     RSpec.configure do |c|
+    #       c.before(:suite)   { establish_connection }
+    #       c.before(:example) { log_in_as :authorized }
+    #       c.around(:example) { |ex| Database.transaction(&ex) }
+    #     end
+    #
+    # @see RSpec.configure
+    # @see Hooks
+    class Configuration
+      include RSpec::Core::Hooks
+
+      # Module that holds `attr_reader` declarations. It's in a separate
+      # module to allow us to override those methods and use `super`.
+      # @private
+      Readers = Module.new
+      include Readers
+
+      # @private
+      class MustBeConfiguredBeforeExampleGroupsError < StandardError; end
+
+      # @private
+      def self.define_reader(name)
+        Readers.class_eval do
+          remove_method name if method_defined?(name)
+          attr_reader name
+        end
+
+        define_method(name) { value_for(name) { super() } }
+      end
+
+      # @private
+      def self.define_aliases(name, alias_name)
+        alias_method alias_name, name
+        alias_method "#{alias_name}=", "#{name}="
+        define_predicate_for alias_name
+      end
+
+      # @private
+      def self.define_predicate_for(*names)
+        names.each { |name| alias_method "#{name}?", name }
+      end
+
+      # @private
+      #
+      # Invoked by the `add_setting` instance method. Use that method on a
+      # `Configuration` instance rather than this class method.
+      def self.add_setting(name, opts={})
+        raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default)
+        attr_writer name
+        add_read_only_setting name
+
+        Array(opts[:alias_with]).each do |alias_name|
+          define_aliases(name, alias_name)
+        end
+      end
+
+      # @private
+      #
+      # As `add_setting` but only add the reader.
+      def self.add_read_only_setting(name, opts={})
+        raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default)
+        define_reader name
+        define_predicate_for name
+      end
+
+      # @macro [attach] add_setting
+      #   @!attribute [rw] $1
+      #   @!method $1=(value)
+      #
+      # @macro [attach] define_reader
+      #   @!attribute [r] $1
+
+      # @macro add_setting
+      # Path to use if no path is provided to the `rspec` command (default:
+      # `"spec"`). Allows you to just type `rspec` instead of `rspec spec` to
+      # run all the examples in the `spec` directory.
+      #
+      # @note Other scripts invoking `rspec` indirectly will ignore this
+      #   setting.
+      add_setting :default_path
+
+      # @macro add_setting
+      # Run examples over DRb (default: `false`). RSpec doesn't supply the DRb
+      # server, but you can use tools like spork.
+      add_setting :drb
+
+      # @macro add_setting
+      # The drb_port (default: nil).
+      add_setting :drb_port
+
+      # @macro add_setting
+      # Default: `$stderr`.
+      add_setting :error_stream
+
+      # Indicates if the DSL has been exposed off of modules and `main`.
+      # Default: true
+      def expose_dsl_globally?
+        Core::DSL.exposed_globally?
+      end
+
+      # Use this to expose the core RSpec DSL via `Module` and the `main`
+      # object. It will be set automatically but you can override it to
+      # remove the DSL.
+      # Default: true
+      def expose_dsl_globally=(value)
+        if value
+          Core::DSL.expose_globally!
+          Core::SharedExampleGroup::TopLevelDSL.expose_globally!
+        else
+          Core::DSL.remove_globally!
+          Core::SharedExampleGroup::TopLevelDSL.remove_globally!
+        end
+      end
+
+      # Determines where deprecation warnings are printed.
+      # Defaults to `$stderr`.
+      # @return [IO, String] IO to write to or filename to write to
+      define_reader :deprecation_stream
+
+      # Determines where deprecation warnings are printed.
+      # @param value [IO, String] IO to write to or filename to write to
+      def deprecation_stream=(value)
+        if @reporter && !value.equal?(@deprecation_stream)
+          warn "RSpec's reporter has already been initialized with " \
+            "#{deprecation_stream.inspect} as the deprecation stream, so your change to "\
+            "`deprecation_stream` will be ignored. You should configure it earlier for " \
+            "it to take effect, or use the `--deprecation-out` CLI option. " \
+            "(Called from #{CallerFilter.first_non_rspec_line})"
+        else
+          @deprecation_stream = value
+        end
+      end
+
+      # @macro add_setting
+      # Clean up and exit after the first failure (default: `false`).
+      add_setting :fail_fast
+
+      # @macro add_setting
+      # Prints the formatter output of your suite without running any
+      # examples or hooks.
+      add_setting :dry_run
+
+      # @macro add_setting
+      # The exit code to return if there are any failures (default: 1).
+      add_setting :failure_exit_code
+
+      # @macro define_reader
+      # Indicates files configured to be required.
+      define_reader :requires
+
+      # @macro define_reader
+      # Returns dirs that have been prepended to the load path by the `-I`
+      # command line option.
+      define_reader :libs
+
+      # @macro add_setting
+      # Determines where RSpec will send its output.
+      # Default: `$stdout`.
+      define_reader :output_stream
+
+      # Set the output stream for reporter.
+      # @attr value [IO] value for output, defaults to $stdout
+      def output_stream=(value)
+        if @reporter && !value.equal?(@output_stream)
+          warn "RSpec's reporter has already been initialized with " \
+            "#{output_stream.inspect} as the output stream, so your change to "\
+            "`output_stream` will be ignored. You should configure it earlier for " \
+            "it to take effect. (Called from #{CallerFilter.first_non_rspec_line})"
+        else
+          @output_stream = value
+        end
+      end
+
+      # @macro define_reader
+      # Load files matching this pattern (default: `'**{,/*/**}/*_spec.rb'`).
+      define_reader :pattern
+
+      # Set pattern to match files to load.
+      # @attr value [String] the filename pattern to filter spec files by
+      def pattern=(value)
+        update_pattern_attr :pattern, value
+      end
+
+      # @macro define_reader
+      # Exclude files matching this pattern.
+      define_reader :exclude_pattern
+
+      # Set pattern to match files to exclude.
+      # @attr value [String] the filename pattern to exclude spec files by
+      def exclude_pattern=(value)
+        update_pattern_attr :exclude_pattern, value
+      end
+
+      # @macro add_setting
+      # Report the times for the slowest examples (default: `false`).
+      # Use this to specify the number of examples to include in the profile.
+      add_setting :profile_examples
+
+      # @macro add_setting
+      # Run all examples if none match the configured filters
+      # (default: `false`).
+      add_setting :run_all_when_everything_filtered
+
+      # @macro add_setting
+      # Color to use to indicate success.
+      # @param color [Symbol] defaults to `:green` but can be set to one of the
+      #   following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
+      #   :cyan]`
+      add_setting :success_color
+
+      # @macro add_setting
+      # Color to use to print pending examples.
+      # @param color [Symbol] defaults to `:yellow` but can be set to one of the
+      #   following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
+      #   :cyan]`
+      add_setting :pending_color
+
+      # @macro add_setting
+      # Color to use to indicate failure.
+      # @param color [Symbol] defaults to `:red` but can be set to one of the
+      #   following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
+      #   :cyan]`
+      add_setting :failure_color
+
+      # @macro add_setting
+      # The default output color.
+      # @param color [Symbol] defaults to `:white` but can be set to one of the
+      #   following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
+      #   :cyan]`
+      add_setting :default_color
+
+      # @macro add_setting
+      # Color used when a pending example is fixed.
+      # @param color [Symbol] defaults to `:blue` but can be set to one of the
+      #   following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
+      #   :cyan]`
+      add_setting :fixed_color
+
+      # @macro add_setting
+      # Color used to print details.
+      # @param color [Symbol] defaults to `:cyan` but can be set to one of the
+      #   following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
+      #   :cyan]`
+      add_setting :detail_color
+
+      # Deprecated. This config option was added in RSpec 2 to pave the way
+      # for this being the default behavior in RSpec 3. Now this option is
+      # a no-op.
+      def treat_symbols_as_metadata_keys_with_true_values=(_value)
+        RSpec.deprecate(
+          "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=",
+          :message => "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values= " \
+                      "is deprecated, it is now set to true as default and " \
+                      "setting it to false has no effect."
+        )
+      end
+
+      # Record the start time of the spec suite to measure load time.
+      add_setting :start_time
+
+      # @private
+      add_setting :tty
+      # @private
+      attr_writer :files_to_run
+      # @private
+      attr_accessor :filter_manager
+      # @private
+      attr_accessor :static_config_filter_manager
+      # @private
+      attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files
+
+      def initialize
+        # rubocop:disable Style/GlobalVars
+        @start_time = $_rspec_core_load_started_at || ::RSpec::Core::Time.now
+        # rubocop:enable Style/GlobalVars
+        @expectation_frameworks = []
+        @include_modules = FilterableItemRepository::QueryOptimized.new(:any?)
+        @extend_modules  = FilterableItemRepository::QueryOptimized.new(:any?)
+        @prepend_modules = FilterableItemRepository::QueryOptimized.new(:any?)
+
+        @before_suite_hooks = []
+        @after_suite_hooks  = []
+
+        @mock_framework = nil
+        @files_or_directories_to_run = []
+        @loaded_spec_files = Set.new
+        @color = false
+        @pattern = '**{,/*/**}/*_spec.rb'
+        @exclude_pattern = ''
+        @failure_exit_code = 1
+        @spec_files_loaded = false
+
+        @backtrace_formatter = BacktraceFormatter.new
+
+        @default_path = 'spec'
+        @deprecation_stream = $stderr
+        @output_stream = $stdout
+        @reporter = nil
+        @reporter_buffer = nil
+        @filter_manager = FilterManager.new
+        @static_config_filter_manager = FilterManager.new
+        @ordering_manager = Ordering::ConfigurationManager.new
+        @preferred_options = {}
+        @failure_color = :red
+        @success_color = :green
+        @pending_color = :yellow
+        @default_color = :white
+        @fixed_color = :blue
+        @detail_color = :cyan
+        @profile_examples = false
+        @requires = []
+        @libs = []
+        @derived_metadata_blocks = FilterableItemRepository::QueryOptimized.new(:any?)
+      end
+
+      # @private
+      #
+      # Used to set higher priority option values from the command line.
+      def force(hash)
+        ordering_manager.force(hash)
+        @preferred_options.merge!(hash)
+      end
+
+      # @private
+      def reset
+        @spec_files_loaded = false
+        @reporter = nil
+        @formatter_loader = nil
+      end
+
+      # @private
+      def reset_filters
+        self.filter_manager = FilterManager.new
+        filter_manager.include_only(
+          Metadata.deep_hash_dup(static_config_filter_manager.inclusions.rules)
+        )
+        filter_manager.exclude_only(
+          Metadata.deep_hash_dup(static_config_filter_manager.exclusions.rules)
+        )
+      end
+
+      # @overload add_setting(name)
+      # @overload add_setting(name, opts)
+      # @option opts [Symbol] :default
+      #
+      #   Set a default value for the generated getter and predicate methods:
+      #
+      #       add_setting(:foo, :default => "default value")
+      #
+      # @option opts [Symbol] :alias_with
+      #
+      #   Use `:alias_with` to alias the setter, getter, and predicate to
+      #   another name, or names:
+      #
+      #       add_setting(:foo, :alias_with => :bar)
+      #       add_setting(:foo, :alias_with => [:bar, :baz])
+      #
+      # Adds a custom setting to the RSpec.configuration object.
+      #
+      #     RSpec.configuration.add_setting :foo
+      #
+      # Used internally and by extension frameworks like rspec-rails, so they
+      # can add config settings that are domain specific. For example:
+      #
+      #     RSpec.configure do |c|
+      #       c.add_setting :use_transactional_fixtures,
+      #         :default => true,
+      #         :alias_with => :use_transactional_examples
+      #     end
+      #
+      # `add_setting` creates three methods on the configuration object, a
+      # setter, a getter, and a predicate:
+      #
+      #     RSpec.configuration.foo=(value)
+      #     RSpec.configuration.foo
+      #     RSpec.configuration.foo? # Returns true if foo returns anything but nil or false.
+      def add_setting(name, opts={})
+        default = opts.delete(:default)
+        (class << self; self; end).class_exec do
+          add_setting(name, opts)
+        end
+        __send__("#{name}=", default) if default
+      end
+
+      # Returns the configured mock framework adapter module.
+      def mock_framework
+        if @mock_framework.nil?
+          begin
+            mock_with :rspec
+          rescue LoadError
+            mock_with :nothing
+          end
+        end
+        @mock_framework
+      end
+
+      # Delegates to mock_framework=(framework).
+      def mock_framework=(framework)
+        mock_with framework
+      end
+
+      # Regexps used to exclude lines from backtraces.
+      #
+      # Excludes lines from ruby (and jruby) source, installed gems, anything
+      # in any "bin" directory, and any of the RSpec libs (outside gem
+      # installs) by default.
+      #
+      # You can modify the list via the getter, or replace it with the setter.
+      #
+      # To override this behaviour and display a full backtrace, use
+      # `--backtrace` on the command line, in a `.rspec` file, or in the
+      # `rspec_options` attribute of RSpec's rake task.
+      def backtrace_exclusion_patterns
+        @backtrace_formatter.exclusion_patterns
+      end
+
+      # Set regular expressions used to exclude lines in backtrace.
+      # @param patterns [Regexp] set the backtrace exlusion pattern
+      def backtrace_exclusion_patterns=(patterns)
+        @backtrace_formatter.exclusion_patterns = patterns
+      end
+
+      # Regexps used to include lines in backtraces.
+      #
+      # Defaults to [Regexp.new Dir.getwd].
+      #
+      # Lines that match an exclusion _and_ an inclusion pattern
+      # will be included.
+      #
+      # You can modify the list via the getter, or replace it with the setter.
+      def backtrace_inclusion_patterns
+        @backtrace_formatter.inclusion_patterns
+      end
+
+      # Set regular expressions used to include lines in backtrace.
+      # @attr patterns [Regexp] set backtrace_formatter inclusion_patterns
+      def backtrace_inclusion_patterns=(patterns)
+        @backtrace_formatter.inclusion_patterns = patterns
+      end
+
+      # Adds {#backtrace_exclusion_patterns} that will filter lines from
+      # the named gems from backtraces.
+      #
+      # @param gem_names [Array<String>] Names of the gems to filter
+      #
+      # @example
+      #   RSpec.configure do |config|
+      #     config.filter_gems_from_backtrace "rack", "rake"
+      #   end
+      #
+      # @note The patterns this adds will match the named gems in their common
+      #   locations (e.g. system gems, vendored with bundler, installed as a
+      #   :git dependency with bundler, etc) but is not guaranteed to work for
+      #   all possible gem locations. For example, if you have the gem source
+      #   in a directory with a completely unrelated name, and use bundler's
+      #   :path option, this will not filter it.
+      def filter_gems_from_backtrace(*gem_names)
+        gem_names.each do |name|
+          @backtrace_formatter.filter_gem(name)
+        end
+      end
+
+      # @private
+      MOCKING_ADAPTERS = {
+        :rspec    => :RSpec,
+        :flexmock => :Flexmock,
+        :rr       => :RR,
+        :mocha    => :Mocha,
+        :nothing  => :Null
+      }
+
+      # Sets the mock framework adapter module.
+      #
+      # `framework` can be a Symbol or a Module.
+      #
+      # Given any of `:rspec`, `:mocha`, `:flexmock`, or `:rr`, configures the
+      # named framework.
+      #
+      # Given `:nothing`, configures no framework. Use this if you don't use
+      # any mocking framework to save a little bit of overhead.
+      #
+      # Given a Module, includes that module in every example group. The module
+      # should adhere to RSpec's mock framework adapter API:
+      #
+      #     setup_mocks_for_rspec
+      #       - called before each example
+      #
+      #     verify_mocks_for_rspec
+      #       - called after each example if the example hasn't yet failed.
+      #         Framework should raise an exception when expectations fail
+      #
+      #     teardown_mocks_for_rspec
+      #       - called after verify_mocks_for_rspec (even if there are errors)
+      #
+      # If the module responds to `configuration` and `mock_with` receives a
+      # block, it will yield the configuration object to the block e.g.
+      #
+      #     config.mock_with OtherMockFrameworkAdapter do |mod_config|
+      #       mod_config.custom_setting = true
+      #     end
+      def mock_with(framework)
+        framework_module =
+          if framework.is_a?(Module)
+            framework
+          else
+            const_name = MOCKING_ADAPTERS.fetch(framework) do
+              raise ArgumentError,
+                    "Unknown mocking framework: #{framework.inspect}. " \
+                    "Pass a module or one of #{MOCKING_ADAPTERS.keys.inspect}"
+            end
+
+            RSpec::Support.require_rspec_core "mocking_adapters/#{const_name.to_s.downcase}"
+            RSpec::Core::MockingAdapters.const_get(const_name)
+          end
+
+        new_name, old_name = [framework_module, @mock_framework].map do |mod|
+          mod.respond_to?(:framework_name) ?  mod.framework_name : :unnamed
+        end
+
+        unless new_name == old_name
+          assert_no_example_groups_defined(:mock_framework)
+        end
+
+        if block_given?
+          raise "#{framework_module} must respond to `configuration` so that " \
+                "mock_with can yield it." unless framework_module.respond_to?(:configuration)
+          yield framework_module.configuration
+        end
+
+        @mock_framework = framework_module
+      end
+
+      # Returns the configured expectation framework adapter module(s)
+      def expectation_frameworks
+        if @expectation_frameworks.empty?
+          begin
+            expect_with :rspec
+          rescue LoadError
+            expect_with Module.new
+          end
+        end
+        @expectation_frameworks
+      end
+
+      # Delegates to expect_with(framework).
+      def expectation_framework=(framework)
+        expect_with(framework)
+      end
+
+      # Sets the expectation framework module(s) to be included in each example
+      # group.
+      #
+      # `frameworks` can be `:rspec`, `:test_unit`, `:minitest`, a custom
+      # module, or any combination thereof:
+      #
+      #     config.expect_with :rspec
+      #     config.expect_with :test_unit
+      #     config.expect_with :minitest
+      #     config.expect_with :rspec, :minitest
+      #     config.expect_with OtherExpectationFramework
+      #
+      # RSpec will translate `:rspec`, `:minitest`, and `:test_unit` into the
+      # appropriate modules.
+      #
+      # ## Configuration
+      #
+      # If the module responds to `configuration`, `expect_with` will
+      # yield the `configuration` object if given a block:
+      #
+      #     config.expect_with OtherExpectationFramework do |custom_config|
+      #       custom_config.custom_setting = true
+      #     end
+      def expect_with(*frameworks)
+        modules = frameworks.map do |framework|
+          case framework
+          when Module
+            framework
+          when :rspec
+            require 'rspec/expectations'
+            ::RSpec::Matchers
+          when :test_unit
+            require 'rspec/core/test_unit_assertions_adapter'
+            ::RSpec::Core::TestUnitAssertionsAdapter
+          when :minitest
+            require 'rspec/core/minitest_assertions_adapter'
+            ::RSpec::Core::MinitestAssertionsAdapter
+          else
+            raise ArgumentError, "#{framework.inspect} is not supported"
+          end
+        end
+
+        if (modules - @expectation_frameworks).any?
+          assert_no_example_groups_defined(:expect_with)
+        end
+
+        if block_given?
+          raise "expect_with only accepts a block with a single argument. " \
+                "Call expect_with #{modules.length} times, " \
+                "once with each argument, instead." if modules.length > 1
+          raise "#{modules.first} must respond to `configuration` so that " \
+                "expect_with can yield it." unless modules.first.respond_to?(:configuration)
+          yield modules.first.configuration
+        end
+
+        @expectation_frameworks.push(*modules)
+      end
+
+      # Check if full backtrace is enabled.
+      # @return [Boolean] is full backtrace enabled
+      def full_backtrace?
+        @backtrace_formatter.full_backtrace?
+      end
+
+      # Toggle full backtrace.
+      # @attr true_or_false [Boolean] toggle full backtrace display
+      def full_backtrace=(true_or_false)
+        @backtrace_formatter.full_backtrace = true_or_false
+      end
+
+      # Returns the configuration option for color, but should not
+      # be used to check if color is supported.
+      #
+      # @see color_enabled?
+      # @return [Boolean]
+      def color
+        value_for(:color) { @color }
+      end
+
+      # Check if color is enabled for a particular output.
+      # @param output [IO] an output stream to use, defaults to the current
+      #        `output_stream`
+      # @return [Boolean]
+      def color_enabled?(output=output_stream)
+        output_to_tty?(output) && color
+      end
+
+      # Toggle output color.
+      # @attr true_or_false [Boolean] toggle color enabled
+      def color=(true_or_false)
+        return unless true_or_false
+
+        if RSpec::Support::OS.windows? && !ENV['ANSICON']
+          RSpec.warning "You must use ANSICON 1.31 or later " \
+                        "(http://adoxa.3eeweb.com/ansicon/) to use colour " \
+                        "on Windows"
+          @color = false
+        else
+          @color = true
+        end
+      end
+
+      # @private
+      def libs=(libs)
+        libs.map do |lib|
+          @libs.unshift lib
+          $LOAD_PATH.unshift lib
+        end
+      end
+
+      # Run examples matching on `description` in all files to run.
+      # @param description [String, Regexp] the pattern to filter on
+      def full_description=(description)
+        filter_run :full_description => Regexp.union(*Array(description).map { |d| Regexp.new(d) })
+      end
+
+      # @return [Array] full description filter
+      def full_description
+        filter.fetch :full_description, nil
+      end
+
+      # @overload add_formatter(formatter)
+      #
+      # Adds a formatter to the formatters collection. `formatter` can be a
+      # string representing any of the built-in formatters (see
+      # `built_in_formatter`), or a custom formatter class.
+      #
+      # ### Note
+      #
+      # For internal purposes, `add_formatter` also accepts the name of a class
+      # and paths to use for output streams, but you should consider that a
+      # private api that may change at any time without notice.
+      def add_formatter(formatter_to_use, *paths)
+        paths << output_stream if paths.empty?
+        formatter_loader.add formatter_to_use, *paths
+      end
+      alias_method :formatter=, :add_formatter
+
+      # The formatter that will be used if no formatter has been set.
+      # Defaults to 'progress'.
+      def default_formatter
+        formatter_loader.default_formatter
+      end
+
+      # Sets a fallback formatter to use if none other has been set.
+      #
+      # @example
+      #
+      #   RSpec.configure do |rspec|
+      #     rspec.default_formatter = 'doc'
+      #   end
+      def default_formatter=(value)
+        formatter_loader.default_formatter = value
+      end
+
+      # Returns a duplicate of the formatters currently loaded in
+      # the `FormatterLoader` for introspection.
+      #
+      # Note as this is a duplicate, any mutations will be disregarded.
+      #
+      # @return [Array] the formatters currently loaded
+      def formatters
+        formatter_loader.formatters.dup
+      end
+
+      # @private
+      def formatter_loader
+        @formatter_loader ||= Formatters::Loader.new(Reporter.new(self))
+      end
+
+      # @private
+      #
+      # This buffer is used to capture all messages sent to the reporter during
+      # reporter initialization. It can then replay those messages after the
+      # formatter is correctly initialized. Otherwise, deprecation warnings
+      # during formatter initialization can cause an infinite loop.
+      class DeprecationReporterBuffer
+        def initialize
+          @calls = []
+        end
+
+        def deprecation(*args)
+          @calls << args
+        end
+
+        def play_onto(reporter)
+          @calls.each do |args|
+            reporter.deprecation(*args)
+          end
+        end
+      end
+
+      # @private
+      def reporter
+        # @reporter_buffer should only ever be set in this method to cover
+        # initialization of @reporter.
+        @reporter_buffer || @reporter ||=
+          begin
+            @reporter_buffer = DeprecationReporterBuffer.new
+            formatter_loader.setup_default output_stream, deprecation_stream
+            @reporter_buffer.play_onto(formatter_loader.reporter)
+            @reporter_buffer = nil
+            formatter_loader.reporter
+          end
+      end
+
+      # @api private
+      #
+      # Defaults `profile_examples` to 10 examples when `@profile_examples` is
+      # `true`.
+      def profile_examples
+        profile = value_for(:profile_examples) { @profile_examples }
+        if profile && !profile.is_a?(Integer)
+          10
+        else
+          profile
+        end
+      end
+
+      # @private
+      def files_or_directories_to_run=(*files)
+        files = files.flatten
+        files << default_path if (command == 'rspec' || Runner.running_in_drb?) && default_path && files.empty?
+        @files_or_directories_to_run = files
+        @files_to_run = nil
+      end
+
+      # The spec files RSpec will run.
+      # @return [Array] specified files about to run
+      def files_to_run
+        @files_to_run ||= get_files_to_run(@files_or_directories_to_run)
+      end
+
+      # Creates a method that delegates to `example` including the submitted
+      # `args`. Used internally to add variants of `example` like `pending`:
+      # @param name [String] example name alias
+      # @param args [Array<Symbol>, Hash] metadata for the generated example
+      #
+      # @note The specific example alias below (`pending`) is already
+      #   defined for you.
+      # @note Use with caution. This extends the language used in your
+      #   specs, but does not add any additional documentation. We use this
+      #   in RSpec to define methods like `focus` and `xit`, but we also add
+      #   docs for those methods.
+      #
+      # @example
+      #   RSpec.configure do |config|
+      #     config.alias_example_to :pending, :pending => true
+      #   end
+      #
+      #   # This lets you do this:
+      #
+      #   describe Thing do
+      #     pending "does something" do
+      #       thing = Thing.new
+      #     end
+      #   end
+      #
+      #   # ... which is the equivalent of
+      #
+      #   describe Thing do
+      #     it "does something", :pending => true do
+      #       thing = Thing.new
+      #     end
+      #   end
+      def alias_example_to(name, *args)
+        extra_options = Metadata.build_hash_from(args)
+        RSpec::Core::ExampleGroup.define_example_method(name, extra_options)
+      end
+
+      # Creates a method that defines an example group with the provided
+      # metadata. Can be used to define example group/metadata shortcuts.
+      #
+      # @example
+      #   RSpec.configure do |config|
+      #     config.alias_example_group_to :describe_model, :type => :model
+      #   end
+      #
+      #   shared_context_for "model tests", :type => :model do
+      #     # define common model test helper methods, `let` declarations, etc
+      #   end
+      #
+      #   # This lets you do this:
+      #
+      #   RSpec.describe_model User do
+      #   end
+      #
+      #   # ... which is the equivalent of
+      #
+      #   RSpec.describe User, :type => :model do
+      #   end
+      #
+      # @note The defined aliased will also be added to the top level
+      #       (e.g. `main` and from within modules) if
+      #       `expose_dsl_globally` is set to true.
+      # @see #alias_example_to
+      # @see #expose_dsl_globally=
+      def alias_example_group_to(new_name, *args)
+        extra_options = Metadata.build_hash_from(args)
+        RSpec::Core::ExampleGroup.define_example_group_method(new_name, extra_options)
+      end
+
+      # Define an alias for it_should_behave_like that allows different
+      # language (like "it_has_behavior" or "it_behaves_like") to be
+      # employed when including shared examples.
+      #
+      # @example
+      #   RSpec.configure do |config|
+      #     config.alias_it_behaves_like_to(:it_has_behavior, 'has behavior:')
+      #   end
+      #
+      #   # allows the user to include a shared example group like:
+      #
+      #   describe Entity do
+      #     it_has_behavior 'sortability' do
+      #       let(:sortable) { Entity.new }
+      #     end
+      #   end
+      #
+      #   # which is reported in the output as:
+      #   # Entity
+      #   #   has behavior: sortability
+      #   #     ...sortability examples here
+      #
+      # @note Use with caution. This extends the language used in your
+      #   specs, but does not add any additional documentation. We use this
+      #   in RSpec to define `it_should_behave_like` (for backward
+      #   compatibility), but we also add docs for that method.
+      def alias_it_behaves_like_to(new_name, report_label='')
+        RSpec::Core::ExampleGroup.define_nested_shared_group_method(new_name, report_label)
+      end
+      alias_method :alias_it_should_behave_like_to, :alias_it_behaves_like_to
+
+      # Adds key/value pairs to the `inclusion_filter`. If `args`
+      # includes any symbols that are not part of the hash, each symbol
+      # is treated as a key in the hash with the value `true`.
+      #
+      # ### Note
+      #
+      # Filters set using this method can be overridden from the command line
+      # or config files (e.g. `.rspec`).
+      #
+      # @example
+      #     # Given this declaration.
+      #     describe "something", :foo => 'bar' do
+      #       # ...
+      #     end
+      #
+      #     # Any of the following will include that group.
+      #     config.filter_run_including :foo => 'bar'
+      #     config.filter_run_including :foo => /^ba/
+      #     config.filter_run_including :foo => lambda {|v| v == 'bar'}
+      #     config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
+      #
+      #     # Given a proc with an arity of 1, the lambda is passed the value
+      #     # related to the key, e.g.
+      #     config.filter_run_including :foo => lambda {|v| v == 'bar'}
+      #
+      #     # Given a proc with an arity of 2, the lambda is passed the value
+      #     # related to the key, and the metadata itself e.g.
+      #     config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
+      #
+      #     filter_run_including :foo # same as filter_run_including :foo => true
+      def filter_run_including(*args)
+        meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
+        filter_manager.include_with_low_priority meta
+        static_config_filter_manager.include_with_low_priority Metadata.deep_hash_dup(meta)
+      end
+
+      alias_method :filter_run, :filter_run_including
+
+      # Clears and reassigns the `inclusion_filter`. Set to `nil` if you don't
+      # want any inclusion filter at all.
+      #
+      # ### Warning
+      #
+      # This overrides any inclusion filters/tags set on the command line or in
+      # configuration files.
+      def inclusion_filter=(filter)
+        meta = Metadata.build_hash_from([filter], :warn_about_example_group_filtering)
+        filter_manager.include_only meta
+      end
+
+      alias_method :filter=, :inclusion_filter=
+
+      # Returns the `inclusion_filter`. If none has been set, returns an empty
+      # hash.
+      def inclusion_filter
+        filter_manager.inclusions
+      end
+
+      alias_method :filter, :inclusion_filter
+
+      # Adds key/value pairs to the `exclusion_filter`. If `args`
+      # includes any symbols that are not part of the hash, each symbol
+      # is treated as a key in the hash with the value `true`.
+      #
+      # ### Note
+      #
+      # Filters set using this method can be overridden from the command line
+      # or config files (e.g. `.rspec`).
+      #
+      # @example
+      #     # Given this declaration.
+      #     describe "something", :foo => 'bar' do
+      #       # ...
+      #     end
+      #
+      #     # Any of the following will exclude that group.
+      #     config.filter_run_excluding :foo => 'bar'
+      #     config.filter_run_excluding :foo => /^ba/
+      #     config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
+      #     config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
+      #
+      #     # Given a proc with an arity of 1, the lambda is passed the value
+      #     # related to the key, e.g.
+      #     config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
+      #
+      #     # Given a proc with an arity of 2, the lambda is passed the value
+      #     # related to the key, and the metadata itself e.g.
+      #     config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
+      #
+      #     filter_run_excluding :foo # same as filter_run_excluding :foo => true
+      def filter_run_excluding(*args)
+        meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
+        filter_manager.exclude_with_low_priority meta
+        static_config_filter_manager.exclude_with_low_priority Metadata.deep_hash_dup(meta)
+      end
+
+      # Clears and reassigns the `exclusion_filter`. Set to `nil` if you don't
+      # want any exclusion filter at all.
+      #
+      # ### Warning
+      #
+      # This overrides any exclusion filters/tags set on the command line or in
+      # configuration files.
+      def exclusion_filter=(filter)
+        meta = Metadata.build_hash_from([filter], :warn_about_example_group_filtering)
+        filter_manager.exclude_only meta
+      end
+
+      # Returns the `exclusion_filter`. If none has been set, returns an empty
+      # hash.
+      def exclusion_filter
+        filter_manager.exclusions
+      end
+
+      # Tells RSpec to include `mod` in example groups. Methods defined in
+      # `mod` are exposed to examples (not example groups). Use `filters` to
+      # constrain the groups or examples in which to include the module.
+      #
+      # @example
+      #
+      #     module AuthenticationHelpers
+      #       def login_as(user)
+      #         # ...
+      #       end
+      #     end
+      #
+      #     module UserHelpers
+      #       def users(username)
+      #         # ...
+      #       end
+      #     end
+      #
+      #     RSpec.configure do |config|
+      #       config.include(UserHelpers) # included in all modules
+      #       config.include(AuthenticationHelpers, :type => :request)
+      #     end
+      #
+      #     describe "edit profile", :type => :request do
+      #       it "can be viewed by owning user" do
+      #         login_as users(:jdoe)
+      #         get "/profiles/jdoe"
+      #         assert_select ".username", :text => 'jdoe'
+      #       end
+      #     end
+      #
+      # @note Filtered module inclusions can also be applied to
+      #   individual examples that have matching metadata. Just like
+      #   Ruby's object model is that every object has a singleton class
+      #   which has only a single instance, RSpec's model is that every
+      #   example has a singleton example group containing just the one
+      #   example.
+      #
+      # @see #extend
+      # @see #prepend
+      def include(mod, *filters)
+        meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
+        @include_modules.append(mod, meta)
+      end
+
+      # Tells RSpec to extend example groups with `mod`. Methods defined in
+      # `mod` are exposed to example groups (not examples). Use `filters` to
+      # constrain the groups to extend.
+      #
+      # Similar to `include`, but behavior is added to example groups, which
+      # are classes, rather than the examples, which are instances of those
+      # classes.
+      #
+      # @example
+      #
+      #     module UiHelpers
+      #       def run_in_browser
+      #         # ...
+      #       end
+      #     end
+      #
+      #     RSpec.configure do |config|
+      #       config.extend(UiHelpers, :type => :request)
+      #     end
+      #
+      #     describe "edit profile", :type => :request do
+      #       run_in_browser
+      #
+      #       it "does stuff in the client" do
+      #         # ...
+      #       end
+      #     end
+      #
+      # @see #include
+      # @see #prepend
+      def extend(mod, *filters)
+        meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
+        @extend_modules.append(mod, meta)
+      end
+
+      if RSpec::Support::RubyFeatures.module_prepends_supported?
+        # Tells RSpec to prepend example groups with `mod`. Methods defined in
+        # `mod` are exposed to examples (not example groups). Use `filters` to
+        # constrain the groups in which to prepend the module.
+        #
+        # Similar to `include`, but module is included before the example group's class
+        # in the ancestor chain.
+        #
+        # @example
+        #
+        #     module OverrideMod
+        #       def override_me
+        #         "overridden"
+        #       end
+        #     end
+        #
+        #     RSpec.configure do |config|
+        #       config.prepend(OverrideMod, :method => :prepend)
+        #     end
+        #
+        #     describe "overriding example's class", :method => :prepend do
+        #       it "finds the user" do
+        #         self.class.class_eval do
+        #           def override_me
+        #           end
+        #         end
+        #         override_me # => "overridden"
+        #         # ...
+        #       end
+        #     end
+        #
+        # @see #include
+        # @see #extend
+        def prepend(mod, *filters)
+          meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
+          @prepend_modules.append(mod, meta)
+        end
+      end
+
+      # @private
+      #
+      # Used internally to extend a group with modules using `include`, `prepend` and/or
+      # `extend`.
+      def configure_group(group)
+        configure_group_with group, @include_modules, :safe_include
+        configure_group_with group, @extend_modules,  :safe_extend
+        configure_group_with group, @prepend_modules, :safe_prepend
+      end
+
+      # @private
+      def configure_group_with(group, module_list, application_method)
+        module_list.items_for(group.metadata).each do |mod|
+          __send__(application_method, mod, group)
+        end
+      end
+
+      # @private
+      #
+      # Used internally to extend the singleton class of a single example's
+      # example group instance with modules using `include` and/or `extend`.
+      def configure_example(example)
+        # We replace the metadata so that SharedExampleGroupModule#included
+        # has access to the example's metadata[:location].
+        example.example_group_instance.singleton_class.with_replaced_metadata(example.metadata) do
+          @include_modules.items_for(example.metadata).each do |mod|
+            safe_include(mod, example.example_group_instance.singleton_class)
+          end
+        end
+      end
+
+      if RSpec::Support::RubyFeatures.module_prepends_supported?
+        # @private
+        def safe_prepend(mod, host)
+          host.__send__(:prepend, mod) unless host < mod
+        end
+      end
+
+      # @private
+      def requires=(paths)
+        directories = ['lib', default_path].select { |p| File.directory? p }
+        RSpec::Core::RubyProject.add_to_load_path(*directories)
+        paths.each { |path| require path }
+        @requires += paths
+      end
+
+      # @private
+      if RUBY_VERSION.to_f >= 1.9
+        # @private
+        def safe_include(mod, host)
+          host.__send__(:include, mod) unless host < mod
+        end
+
+        # @private
+        def safe_extend(mod, host)
+          host.extend(mod) unless host.singleton_class < mod
+        end
+      else
+        # @private
+        def safe_include(mod, host)
+          host.__send__(:include, mod) unless host.included_modules.include?(mod)
+        end
+
+        # @private
+        def safe_extend(mod, host)
+          host.extend(mod) unless (class << host; self; end).included_modules.include?(mod)
+        end
+      end
+
+      # @private
+      def configure_mock_framework
+        RSpec::Core::ExampleGroup.__send__(:include, mock_framework)
+        conditionally_disable_mocks_monkey_patching
+      end
+
+      # @private
+      def configure_expectation_framework
+        expectation_frameworks.each do |framework|
+          RSpec::Core::ExampleGroup.__send__(:include, framework)
+        end
+        conditionally_disable_expectations_monkey_patching
+      end
+
+      # @private
+      def load_spec_files
+        files_to_run.uniq.each do |f|
+          file = File.expand_path(f)
+          load file
+          loaded_spec_files << file
+        end
+
+        @spec_files_loaded = true
+      end
+
+      # @private
+      DEFAULT_FORMATTER = lambda { |string| string }
+
+      # Formats the docstring output using the block provided.
+      #
+      # @example
+      #   # This will strip the descriptions of both examples and example
+      #   # groups.
+      #   RSpec.configure do |config|
+      #     config.format_docstrings { |s| s.strip }
+      #   end
+      def format_docstrings(&block)
+        @format_docstrings_block = block_given? ? block : DEFAULT_FORMATTER
+      end
+
+      # @private
+      def format_docstrings_block
+        @format_docstrings_block ||= DEFAULT_FORMATTER
+      end
+
+      # @private
+      # @macro [attach] delegate_to_ordering_manager
+      #   @!method $1
+      def self.delegate_to_ordering_manager(*methods)
+        methods.each do |method|
+          define_method method do |*args, &block|
+            ordering_manager.__send__(method, *args, &block)
+          end
+        end
+      end
+
+      # @macro delegate_to_ordering_manager
+      #
+      # Sets the seed value and sets the default global ordering to random.
+      delegate_to_ordering_manager :seed=
+
+      # @macro delegate_to_ordering_manager
+      # Seed for random ordering (default: generated randomly each run).
+      #
+      # When you run specs with `--order random`, RSpec generates a random seed
+      # for the randomization and prints it to the `output_stream` (assuming
+      # you're using RSpec's built-in formatters). If you discover an ordering
+      # dependency (i.e. examples fail intermittently depending on order), set
+      # this (on Configuration or on the command line with `--seed`) to run
+      # using the same seed while you debug the issue.
+      #
+      # We recommend, actually, that you use the command line approach so you
+      # don't accidentally leave the seed encoded.
+      delegate_to_ordering_manager :seed
+
+      # @macro delegate_to_ordering_manager
+      #
+      # Sets the default global order and, if order is `'rand:<seed>'`, also
+      # sets the seed.
+      delegate_to_ordering_manager :order=
+
+      # @macro delegate_to_ordering_manager
+      # Registers a named ordering strategy that can later be
+      # used to order an example group's subgroups by adding
+      # `:order => <name>` metadata to the example group.
+      #
+      # @param name [Symbol] The name of the ordering.
+      # @yield Block that will order the given examples or example groups
+      # @yieldparam list [Array<RSpec::Core::Example>,
+      #   Array<RSpec::Core::ExampleGroup>] The examples or groups to order
+      # @yieldreturn [Array<RSpec::Core::Example>,
+      #   Array<RSpec::Core::ExampleGroup>] The re-ordered examples or groups
+      #
+      # @example
+      #   RSpec.configure do |rspec|
+      #     rspec.register_ordering :reverse do |list|
+      #       list.reverse
+      #     end
+      #   end
+      #
+      #   describe MyClass, :order => :reverse do
+      #     # ...
+      #   end
+      #
+      # @note Pass the symbol `:global` to set the ordering strategy that
+      #   will be used to order the top-level example groups and any example
+      #   groups that do not have declared `:order` metadata.
+      delegate_to_ordering_manager :register_ordering
+
+      # @private
+      delegate_to_ordering_manager :seed_used?, :ordering_registry
+
+      # Set Ruby warnings on or off.
+      def warnings=(value)
+        $VERBOSE = !!value
+      end
+
+      # @return [Boolean] Whether or not ruby warnings are enabled.
+      def warnings?
+        $VERBOSE
+      end
+
+      # Exposes the current running example via the named
+      # helper method. RSpec 2.x exposed this via `example`,
+      # but in RSpec 3.0, the example is instead exposed via
+      # an arg yielded to `it`, `before`, `let`, etc. However,
+      # some extension gems (such as Capybara) depend on the
+      # RSpec 2.x's `example` method, so this config option
+      # can be used to maintain compatibility.
+      #
+      # @param method_name [Symbol] the name of the helper method
+      #
+      # @example
+      #
+      #   RSpec.configure do |rspec|
+      #     rspec.expose_current_running_example_as :example
+      #   end
+      #
+      #   describe MyClass do
+      #     before do
+      #       # `example` can be used here because of the above config.
+      #       do_something if example.metadata[:type] == "foo"
+      #     end
+      #   end
+      def expose_current_running_example_as(method_name)
+        ExposeCurrentExample.module_exec do
+          extend RSpec::SharedContext
+          let(method_name) { |ex| ex }
+        end
+
+        include ExposeCurrentExample
+      end
+
+      # @private
+      module ExposeCurrentExample; end
+
+      # Turns deprecation warnings into errors, in order to surface
+      # the full backtrace of the call site. This can be useful when
+      # you need more context to address a deprecation than the
+      # single-line call site normally provided.
+      #
+      # @example
+      #
+      #   RSpec.configure do |rspec|
+      #     rspec.raise_errors_for_deprecations!
+      #   end
+      def raise_errors_for_deprecations!
+        self.deprecation_stream = Formatters::DeprecationFormatter::RaiseErrorStream.new
+      end
+
+      # Enables zero monkey patching mode for RSpec. It removes monkey
+      # patching of the top-level DSL methods (`describe`,
+      # `shared_examples_for`, etc) onto `main` and `Module`, instead
+      # requiring you to prefix these methods with `RSpec.`. It enables
+      # expect-only syntax for rspec-mocks and rspec-expectations. It
+      # simply disables monkey patching on whatever pieces of RSpec
+      # the user is using.
+      #
+      # @note It configures rspec-mocks and rspec-expectations only
+      #   if the user is using those (either explicitly or implicitly
+      #   by not setting `mock_with` or `expect_with` to anything else).
+      #
+      # @note If the user uses this options with `mock_with :mocha`
+      #   (or similiar) they will still have monkey patching active
+      #   in their test environment from mocha.
+      #
+      # @example
+      #
+      #   # It disables all monkey patching.
+      #   RSpec.configure do |config|
+      #     config.disable_monkey_patching!
+      #   end
+      #
+      #   # Is an equivalent to
+      #   RSpec.configure do |config|
+      #     config.expose_dsl_globally = false
+      #
+      #     config.mock_with :rspec do |mocks|
+      #       mocks.syntax = :expect
+      #       mocks.patch_marshal_to_support_partial_doubles = false
+      #     end
+      #
+      #     config.mock_with :rspec do |expectations|
+      #       expectations.syntax = :expect
+      #     end
+      #   end
+      def disable_monkey_patching!
+        self.expose_dsl_globally = false
+        self.disable_monkey_patching = true
+        conditionally_disable_mocks_monkey_patching
+        conditionally_disable_expectations_monkey_patching
+      end
+
+      # @private
+      attr_accessor :disable_monkey_patching
+
+      # Defines a callback that can assign derived metadata values.
+      #
+      # @param filters [Array<Symbol>, Hash] metadata filters that determine
+      #   which example or group metadata hashes the callback will be triggered
+      #   for. If none are given, the callback will be run against the metadata
+      #   hashes of all groups and examples.
+      # @yieldparam metadata [Hash] original metadata hash from an example or
+      #   group. Mutate this in your block as needed.
+      #
+      # @example
+      #   RSpec.configure do |config|
+      #     # Tag all groups and examples in the spec/unit directory with
+      #     # :type => :unit
+      #     config.define_derived_metadata(:file_path => %r{/spec/unit/}) do |metadata|
+      #       metadata[:type] = :unit
+      #     end
+      #   end
+      def define_derived_metadata(*filters, &block)
+        meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
+        @derived_metadata_blocks.append(block, meta)
+      end
+
+      # @private
+      def apply_derived_metadata_to(metadata)
+        @derived_metadata_blocks.items_for(metadata).each do |block|
+          block.call(metadata)
+        end
+      end
+
+      # Defines a `before` hook. See {Hooks#before} for full docs.
+      #
+      # This method differs from {Hooks#before} in only one way: it supports
+      # the `:suite` scope. Hooks with the `:suite` scope will be run once before
+      # the first example of the entire suite is executed.
+      #
+      # @see #prepend_before
+      # @see #after
+      # @see #append_after
+      def before(*args, &block)
+        handle_suite_hook(args, @before_suite_hooks, :push,
+                          Hooks::BeforeHook, block) || super(*args, &block)
+      end
+      alias_method :append_before, :before
+
+      # Adds `block` to the start of the list of `before` blocks in the same
+      # scope (`:example`, `:context`, or `:suite`), in contrast to {#before},
+      # which adds the hook to the end of the list.
+      #
+      # See {Hooks#before} for full `before` hook docs.
+      #
+      # This method differs from {Hooks#prepend_before} in only one way: it supports
+      # the `:suite` scope. Hooks with the `:suite` scope will be run once before
+      # the first example of the entire suite is executed.
+      #
+      # @see #before
+      # @see #after
+      # @see #append_after
+      def prepend_before(*args, &block)
+        handle_suite_hook(args, @before_suite_hooks, :unshift,
+                          Hooks::BeforeHook, block) || super(*args, &block)
+      end
+
+      # Defines a `after` hook. See {Hooks#after} for full docs.
+      #
+      # This method differs from {Hooks#after} in only one way: it supports
+      # the `:suite` scope. Hooks with the `:suite` scope will be run once after
+      # the last example of the entire suite is executed.
+      #
+      # @see #append_after
+      # @see #before
+      # @see #prepend_before
+      def after(*args, &block)
+        handle_suite_hook(args, @after_suite_hooks, :unshift,
+                          Hooks::AfterHook, block) || super(*args, &block)
+      end
+      alias_method :prepend_after, :after
+
+      # Adds `block` to the end of the list of `after` blocks in the same
+      # scope (`:example`, `:context`, or `:suite`), in contrast to {#after},
+      # which adds the hook to the start of the list.
+      #
+      # See {Hooks#after} for full `after` hook docs.
+      #
+      # This method differs from {Hooks#append_after} in only one way: it supports
+      # the `:suite` scope. Hooks with the `:suite` scope will be run once after
+      # the last example of the entire suite is executed.
+      #
+      # @see #append_after
+      # @see #before
+      # @see #prepend_before
+      def append_after(*args, &block)
+        handle_suite_hook(args, @after_suite_hooks, :push,
+                          Hooks::AfterHook, block) || super(*args, &block)
+      end
+
+      # @private
+      def with_suite_hooks
+        return yield if dry_run?
+
+        hook_context = SuiteHookContext.new
+        begin
+          run_hooks_with(@before_suite_hooks, hook_context)
+          yield
+        ensure
+          run_hooks_with(@after_suite_hooks, hook_context)
+        end
+      end
+
+      # @private
+      # Holds the various registered hooks. Here we use a FilterableItemRepository
+      # implementation that is specifically optimized for the read/write patterns
+      # of the config object.
+      def hooks
+        @hooks ||= HookCollections.new(self, FilterableItemRepository::QueryOptimized)
+      end
+
+    private
+
+      def handle_suite_hook(args, collection, append_or_prepend, hook_type, block)
+        scope, meta = *args
+        return nil unless scope == :suite
+
+        if meta
+          # TODO: in RSpec 4, consider raising an error here.
+          # We warn only for backwards compatibility.
+          RSpec.warn_with "WARNING: `:suite` hooks do not support metadata since " \
+                          "they apply to the suite as a whole rather than " \
+                          "any individual example or example group that has metadata. " \
+                          "The metadata you have provided (#{meta.inspect}) will be ignored."
+        end
+
+        collection.__send__(append_or_prepend, hook_type.new(block, {}))
+      end
+
+      def run_hooks_with(hooks, hook_context)
+        hooks.each { |h| h.run(hook_context) }
+      end
+
+      def get_files_to_run(paths)
+        FlatMap.flat_map(paths_to_check(paths)) do |path|
+          path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
+          File.directory?(path) ? gather_directories(path) : extract_location(path)
+        end.sort.uniq
+      end
+
+      def paths_to_check(paths)
+        return paths if pattern_might_load_specs_from_vendored_dirs?
+        paths + [Dir.getwd]
+      end
+
+      def pattern_might_load_specs_from_vendored_dirs?
+        pattern.split(File::SEPARATOR).first.include?('**')
+      end
+
+      def gather_directories(path)
+        include_files = get_matching_files(path, pattern)
+        exclude_files = get_matching_files(path, exclude_pattern)
+        (include_files - exclude_files).sort.uniq
+      end
+
+      def get_matching_files(path, pattern)
+        Dir[file_glob_from(path, pattern)].map { |file| File.expand_path(file) }
+      end
+
+      def file_glob_from(path, pattern)
+        stripped = "{#{pattern.gsub(/\s*,\s*/, ',')}}"
+        return stripped if pattern =~ /^(\.\/)?#{Regexp.escape path}/ || absolute_pattern?(pattern)
+        File.join(path, stripped)
+      end
+
+      if RSpec::Support::OS.windows?
+        def absolute_pattern?(pattern)
+          pattern =~ /\A[A-Z]:\\/ || windows_absolute_network_path?(pattern)
+        end
+
+        def windows_absolute_network_path?(pattern)
+          return false unless ::File::ALT_SEPARATOR
+          pattern.start_with?(::File::ALT_SEPARATOR + ::File::ALT_SEPARATOR)
+        end
+      else
+        def absolute_pattern?(pattern)
+          pattern.start_with?(File::Separator)
+        end
+      end
+
+      def extract_location(path)
+        match = /^(.*?)((?:\:\d+)+)$/.match(path)
+
+        if match
+          captures = match.captures
+          path, lines = captures[0], captures[1][1..-1].split(":").map { |n| n.to_i }
+          filter_manager.add_location path, lines
+        end
+
+        return [] if path == default_path
+        path
+      end
+
+      def command
+        $0.split(File::SEPARATOR).last
+      end
+
+      def value_for(key)
+        @preferred_options.fetch(key) { yield }
+      end
+
+      def assert_no_example_groups_defined(config_option)
+        return unless RSpec.world.example_groups.any?
+
+        raise MustBeConfiguredBeforeExampleGroupsError.new(
+          "RSpec's #{config_option} configuration option must be configured before " \
+          "any example groups are defined, but you have already defined a group."
+        )
+      end
+
+      def output_to_tty?(output=output_stream)
+        tty? || (output.respond_to?(:tty?) && output.tty?)
+      end
+
+      def conditionally_disable_mocks_monkey_patching
+        return unless disable_monkey_patching && rspec_mocks_loaded?
+
+        RSpec::Mocks.configuration.tap do |config|
+          config.syntax = :expect
+          config.patch_marshal_to_support_partial_doubles = false
+        end
+      end
+
+      def conditionally_disable_expectations_monkey_patching
+        return unless disable_monkey_patching && rspec_expectations_loaded?
+
+        RSpec::Expectations.configuration.syntax = :expect
+      end
+
+      def rspec_mocks_loaded?
+        defined?(RSpec::Mocks.configuration)
+      end
+
+      def rspec_expectations_loaded?
+        defined?(RSpec::Expectations.configuration)
+      end
+
+      def update_pattern_attr(name, value)
+        if @spec_files_loaded
+          RSpec.warning "Configuring `#{name}` to #{value} has no effect since " \
+                        "RSpec has already loaded the spec files."
+        end
+
+        instance_variable_set(:"@#{name}", value)
+        @files_to_run = nil
+      end
+    end
+    # rubocop:enable Style/ClassLength
+  end
+end
diff --git a/rspec-core/lib/rspec/core/configuration_options.rb b/rspec-core/lib/rspec/core/configuration_options.rb
new file mode 100644
index 0000000..36b9f5d
--- /dev/null
+++ b/rspec-core/lib/rspec/core/configuration_options.rb
@@ -0,0 +1,180 @@
+require 'erb'
+require 'shellwords'
+require 'set'
+
+module RSpec
+  module Core
+    # Responsible for utilizing externally provided configuration options,
+    # whether via the command line, `.rspec`, `~/.rspec`, `.rspec-local`
+    # or a custom options file.
+    class ConfigurationOptions
+      # @param args [Array<String>] command line arguments
+      def initialize(args)
+        @args = args.dup
+        organize_options
+      end
+
+      # Updates the provided {Configuration} instance based on the provided
+      # external configuration options.
+      #
+      # @param config [Configuration] the configuration instance to update
+      def configure(config)
+        process_options_into config
+        configure_filter_manager config.filter_manager
+        load_formatters_into config
+      end
+
+      # @api private
+      # Updates the provided {FilterManager} based on the filter options.
+      # @param filter_manager [FilterManager] instance to update
+      def configure_filter_manager(filter_manager)
+        @filter_manager_options.each do |command, value|
+          filter_manager.__send__ command, value
+        end
+      end
+
+      # @return [Hash] the final merged options, drawn from all external sources
+      attr_reader :options
+
+    private
+
+      def organize_options
+        @filter_manager_options = []
+
+        @options = (file_options << command_line_options << env_options).each do |opts|
+          @filter_manager_options << [:include, opts.delete(:inclusion_filter)] if opts.key?(:inclusion_filter)
+          @filter_manager_options << [:exclude, opts.delete(:exclusion_filter)] if opts.key?(:exclusion_filter)
+        end
+
+        @options = @options.inject(:libs => [], :requires => []) do |hash, opts|
+          hash.merge(opts) do |key, oldval, newval|
+            [:libs, :requires].include?(key) ? oldval + newval : newval
+          end
+        end
+      end
+
+      UNFORCED_OPTIONS = [
+        :requires, :profile, :drb, :libs, :files_or_directories_to_run,
+        :full_description, :full_backtrace, :tty
+      ].to_set
+
+      UNPROCESSABLE_OPTIONS = [:formatters].to_set
+
+      def force?(key)
+        !UNFORCED_OPTIONS.include?(key)
+      end
+
+      def order(keys)
+        OPTIONS_ORDER.reverse.each do |key|
+          keys.unshift(key) if keys.delete(key)
+        end
+        keys
+      end
+
+      OPTIONS_ORDER = [
+        # It's important to set this before anything that might issue a
+        # deprecation (or otherwise access the reporter).
+        :deprecation_stream,
+
+        # load paths depend on nothing, but must be set before `requires`
+        # to support load-path-relative requires.
+        :libs,
+
+        # `files_or_directories_to_run` uses `default_path` so it must be
+        # set before it.
+        :default_path,
+
+        # These must be set before `requires` to support checking
+        # `config.files_to_run` from within `spec_helper.rb` when a
+        # `-rspec_helper` option is used.
+        :files_or_directories_to_run, :pattern, :exclude_pattern,
+
+        # Necessary so that the `--seed` option is applied before requires,
+        # in case required files do something with the provided seed.
+        # (such as seed global randomization with it).
+        :order,
+
+        # In general, we want to require the specified files as early as
+        # possible. The `--require` option is specifically intended to allow
+        # early requires. For later requires, they can just put the require in
+        # their spec files, but `--require` provides a unique opportunity for
+        # users to instruct RSpec to load an extension file early for maximum
+        # flexibility.
+        :requires
+      ]
+
+      def process_options_into(config)
+        opts = options.reject { |k, _| UNPROCESSABLE_OPTIONS.include? k }
+
+        order(opts.keys).each do |key|
+          force?(key) ? config.force(key => opts[key]) : config.__send__("#{key}=", opts[key])
+        end
+      end
+
+      def load_formatters_into(config)
+        options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters]
+      end
+
+      def file_options
+        custom_options_file ? [custom_options] : [global_options, project_options, local_options]
+      end
+
+      def env_options
+        ENV["SPEC_OPTS"] ? Parser.parse(Shellwords.split(ENV["SPEC_OPTS"])) : {}
+      end
+
+      def command_line_options
+        @command_line_options ||= Parser.parse(@args).merge :files_or_directories_to_run => @args
+      end
+
+      def custom_options
+        options_from(custom_options_file)
+      end
+
+      def local_options
+        @local_options ||= options_from(local_options_file)
+      end
+
+      def project_options
+        @project_options ||= options_from(project_options_file)
+      end
+
+      def global_options
+        @global_options ||= options_from(global_options_file)
+      end
+
+      def options_from(path)
+        Parser.parse(args_from_options_file(path))
+      end
+
+      def args_from_options_file(path)
+        return [] unless path && File.exist?(path)
+        config_string = options_file_as_erb_string(path)
+        FlatMap.flat_map(config_string.split(/\n+/), &:shellsplit)
+      end
+
+      def options_file_as_erb_string(path)
+        ERB.new(File.read(path), nil, '-').result(binding)
+      end
+
+      def custom_options_file
+        command_line_options[:custom_options_file]
+      end
+
+      def project_options_file
+        ".rspec"
+      end
+
+      def local_options_file
+        ".rspec-local"
+      end
+
+      def global_options_file
+        File.join(File.expand_path("~"), ".rspec")
+      rescue ArgumentError
+        RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set"
+        nil
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/drb.rb b/rspec-core/lib/rspec/core/drb.rb
new file mode 100644
index 0000000..55e6392
--- /dev/null
+++ b/rspec-core/lib/rspec/core/drb.rb
@@ -0,0 +1,111 @@
+require 'drb/drb'
+
+module RSpec
+  module Core
+    # @private
+    class DRbRunner
+      def initialize(options, configuration=RSpec.configuration)
+        @options       = options
+        @configuration = configuration
+      end
+
+      def drb_port
+        @options.options[:drb_port] || ENV['RSPEC_DRB'] || 8989
+      end
+
+      def run(err, out)
+        begin
+          DRb.start_service("druby://localhost:0")
+        rescue SocketError, Errno::EADDRNOTAVAIL
+          DRb.start_service("druby://:0")
+        end
+        spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{drb_port}")
+        spec_server.run(drb_argv, err, out)
+      end
+
+      def drb_argv
+        @drb_argv ||= begin
+          @options.configure_filter_manager(@configuration.filter_manager)
+          DRbOptions.new(@options.options, @configuration.filter_manager).options
+        end
+      end
+    end
+
+    # @private
+    class DRbOptions
+      def initialize(submitted_options, filter_manager)
+        @submitted_options = submitted_options
+        @filter_manager = filter_manager
+      end
+
+      def options
+        argv = []
+        argv << "--color"        if @submitted_options[:color]
+        argv << "--profile"      if @submitted_options[:profile_examples]
+        argv << "--backtrace"    if @submitted_options[:full_backtrace]
+        argv << "--tty"          if @submitted_options[:tty]
+        argv << "--fail-fast"    if @submitted_options[:fail_fast]
+        argv << "--options"      << @submitted_options[:custom_options_file] if @submitted_options[:custom_options_file]
+        argv << "--order"        << @submitted_options[:order]               if @submitted_options[:order]
+
+        add_failure_exit_code(argv)
+        add_full_description(argv)
+        add_filter(argv, :inclusion, @filter_manager.inclusions)
+        add_filter(argv, :exclusion, @filter_manager.exclusions)
+        add_formatters(argv)
+        add_libs(argv)
+        add_requires(argv)
+
+        argv + @submitted_options[:files_or_directories_to_run]
+      end
+
+      def add_failure_exit_code(argv)
+        return unless @submitted_options[:failure_exit_code]
+
+        argv << "--failure-exit-code" << @submitted_options[:failure_exit_code].to_s
+      end
+
+      def add_full_description(argv)
+        return unless @submitted_options[:full_description]
+
+        # The argument to --example is regexp-escaped before being stuffed
+        # into a regexp when received for the first time (see OptionParser).
+        # Hence, merely grabbing the source of this regexp will retain the
+        # backslashes, so we must remove them.
+        @submitted_options[:full_description].each do |description|
+          argv << "--example" << description.source.delete('\\')
+        end
+      end
+
+      CONDITIONAL_FILTERS = [:if, :unless]
+
+      def add_filter(argv, name, hash)
+        hash.each_pair do |k, v|
+          next if CONDITIONAL_FILTERS.include?(k)
+          tag = name == :inclusion ? k.to_s : "~#{k}"
+          tag << ":#{v}" if v.is_a?(String)
+          argv << "--tag" << tag
+        end unless hash.empty?
+      end
+
+      def add_formatters(argv)
+        @submitted_options[:formatters].each do |pair|
+          argv << "--format" << pair[0]
+          argv << "--out" << pair[1] if pair[1]
+        end if @submitted_options[:formatters]
+      end
+
+      def add_libs(argv)
+        @submitted_options[:libs].each do |path|
+          argv << "-I" << path
+        end if @submitted_options[:libs]
+      end
+
+      def add_requires(argv)
+        @submitted_options[:requires].each do |path|
+          argv << "--require" << path
+        end if @submitted_options[:requires]
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/dsl.rb b/rspec-core/lib/rspec/core/dsl.rb
new file mode 100644
index 0000000..9f290b9
--- /dev/null
+++ b/rspec-core/lib/rspec/core/dsl.rb
@@ -0,0 +1,96 @@
+module RSpec
+  module Core
+    # DSL defines methods to group examples, most notably `describe`,
+    # and exposes them as class methods of {RSpec}. They can also be
+    # exposed globally (on `main` and instances of `Module`) through
+    # the {Configuration} option `expose_dsl_globally`.
+    #
+    # By default the methods `describe`, `context` and `example_group`
+    # are exposed. These methods define a named context for one or
+    # more examples. The given block is evaluated in the context of
+    # a generated subclass of {RSpec::Core::ExampleGroup}.
+    #
+    # ## Examples:
+    #
+    #     RSpec.describe "something" do
+    #       context "when something is a certain way" do
+    #         it "does something" do
+    #           # example code goes here
+    #         end
+    #       end
+    #     end
+    #
+    # @see ExampleGroup
+    # @see ExampleGroup.example_group
+    module DSL
+      # @private
+      def self.example_group_aliases
+        @example_group_aliases ||= []
+      end
+
+      # @private
+      def self.exposed_globally?
+        @exposed_globally ||= false
+      end
+
+      # @private
+      def self.expose_example_group_alias(name)
+        return if example_group_aliases.include?(name)
+
+        example_group_aliases << name
+
+        (class << RSpec; self; end).__send__(:define_method, name) do |*args, &example_group_block|
+          RSpec.world.register RSpec::Core::ExampleGroup.__send__(name, *args, &example_group_block)
+        end
+
+        expose_example_group_alias_globally(name) if exposed_globally?
+      end
+
+      class << self
+        # @private
+        attr_accessor :top_level
+      end
+
+      # Adds the describe method to Module and the top level binding.
+      # @api private
+      def self.expose_globally!
+        return if exposed_globally?
+
+        example_group_aliases.each do |method_name|
+          expose_example_group_alias_globally(method_name)
+        end
+
+        @exposed_globally = true
+      end
+
+      # Removes the describe method from Module and the top level binding.
+      # @api private
+      def self.remove_globally!
+        return unless exposed_globally?
+
+        example_group_aliases.each do |method_name|
+          change_global_dsl { undef_method method_name }
+        end
+
+        @exposed_globally = false
+      end
+
+      # @private
+      def self.expose_example_group_alias_globally(method_name)
+        change_global_dsl do
+          remove_method(method_name) if method_defined?(method_name)
+          define_method(method_name) { |*a, &b| ::RSpec.__send__(method_name, *a, &b) }
+        end
+      end
+
+      # @private
+      def self.change_global_dsl(&changes)
+        (class << top_level; self; end).class_exec(&changes)
+        Module.class_exec(&changes)
+      end
+    end
+  end
+end
+
+# Capture main without an eval.
+::RSpec::Core::DSL.top_level = self
diff --git a/rspec-core/lib/rspec/core/example.rb b/rspec-core/lib/rspec/core/example.rb
new file mode 100644
index 0000000..8d02d6e
--- /dev/null
+++ b/rspec-core/lib/rspec/core/example.rb
@@ -0,0 +1,538 @@
+module RSpec
+  module Core
+    # Wrapper for an instance of a subclass of {ExampleGroup}. An instance of
+    # `RSpec::Core::Example` is returned by example definition methods
+    # such as {ExampleGroup.it it} and is yielded to the {ExampleGroup.it it},
+    # {Hooks#before before}, {Hooks#after after}, {Hooks#around around},
+    # {MemoizedHelpers::ClassMethods#let let} and
+    # {MemoizedHelpers::ClassMethods#subject subject} blocks.
+    #
+    # This allows us to provide rich metadata about each individual
+    # example without adding tons of methods directly to the ExampleGroup
+    # that users may inadvertantly redefine.
+    #
+    # Useful for configuring logging and/or taking some action based
+    # on the state of an example's metadata.
+    #
+    # @example
+    #
+    #     RSpec.configure do |config|
+    #       config.before do |example|
+    #         log example.description
+    #       end
+    #
+    #       config.after do |example|
+    #         log example.description
+    #       end
+    #
+    #       config.around do |example|
+    #         log example.description
+    #         example.run
+    #       end
+    #     end
+    #
+    #     shared_examples "auditable" do
+    #       it "does something" do
+    #         log "#{example.full_description}: #{auditable.inspect}"
+    #         auditable.should do_something
+    #       end
+    #     end
+    #
+    # @see ExampleGroup
+    # @note Example blocks are evaluated in the context of an instance
+    #   of an `ExampleGroup`, not in the context of an instance of `Example`.
+    class Example
+      # @private
+      #
+      # Used to define methods that delegate to this example's metadata.
+      def self.delegate_to_metadata(key)
+        define_method(key) { @metadata[key] }
+      end
+
+      # @return [ExecutionResult] represents the result of running this example.
+      delegate_to_metadata :execution_result
+      # @return [String] the relative path to the file where this example was
+      #   defined.
+      delegate_to_metadata :file_path
+      # @return [String] the full description (including the docstrings of
+      #   all parent example groups).
+      delegate_to_metadata :full_description
+      # @return [String] the exact source location of this example in a form
+      #   like `./path/to/spec.rb:17`
+      delegate_to_metadata :location
+      # @return [Boolean] flag that indicates that the example is not expected
+      #   to pass. It will be run and will either have a pending result (if a
+      #   failure occurs) or a failed result (if no failure occurs).
+      delegate_to_metadata :pending
+      # @return [Boolean] flag that will cause the example to not run.
+      #   The {ExecutionResult} status will be `:pending`.
+      delegate_to_metadata :skip
+
+      # Returns the string submitted to `example` or its aliases (e.g.
+      # `specify`, `it`, etc). If no string is submitted (e.g.
+      # `it { is_expected.to do_something }`) it returns the message generated
+      # by the matcher if there is one, otherwise returns a message including
+      # the location of the example.
+      def description
+        description = if metadata[:description].to_s.empty?
+                        location_description
+                      else
+                        metadata[:description]
+                      end
+
+        RSpec.configuration.format_docstrings_block.call(description)
+      end
+
+      # Returns a description of the example that always includes the location.
+      def inspect_output
+        inspect_output = "\"#{description}\""
+        unless metadata[:description].to_s.empty?
+          inspect_output << " (#{location})"
+        end
+        inspect_output
+      end
+
+      # Returns the argument that can be passed to the `rspec` command to rerun this example.
+      def rerun_argument
+        loaded_spec_files = RSpec.configuration.loaded_spec_files
+
+        Metadata.ascending(metadata) do |meta|
+          return meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path])
+        end
+      end
+
+      # @attr_reader
+      #
+      # Returns the first exception raised in the context of running this
+      # example (nil if no exception is raised).
+      attr_reader :exception
+
+      # @attr_reader
+      #
+      # Returns the metadata object associated with this example.
+      attr_reader :metadata
+
+      # @attr_reader
+      # @private
+      #
+      # Returns the example_group_instance that provides the context for
+      # running this example.
+      attr_reader :example_group_instance
+
+      # @attr
+      # @private
+      attr_accessor :clock
+
+      # Creates a new instance of Example.
+      # @param example_group_class [Class] the subclass of ExampleGroup in which
+      #   this Example is declared
+      # @param description [String] the String passed to the `it` method (or
+      #   alias)
+      # @param user_metadata [Hash] additional args passed to `it` to be used as
+      #   metadata
+      # @param example_block [Proc] the block of code that represents the
+      #   example
+      # @api private
+      def initialize(example_group_class, description, user_metadata, example_block=nil)
+        @example_group_class = example_group_class
+        @example_block       = example_block
+
+        @metadata = Metadata::ExampleHash.create(
+          @example_group_class.metadata, user_metadata, description, example_block
+        )
+
+        @example_group_instance = @exception = nil
+        @clock = RSpec::Core::Time
+      end
+
+      # Returns the example group class that provides the context for running
+      # this example.
+      def example_group
+        @example_group_class
+      end
+
+      alias_method :pending?, :pending
+      alias_method :skipped?, :skip
+
+      # @api private
+      # instance_execs the block passed to the constructor in the context of
+      # the instance of {ExampleGroup}.
+      # @param example_group_instance the instance of an ExampleGroup subclass
+      def run(example_group_instance, reporter)
+        @example_group_instance = example_group_instance
+        hooks.register_global_singleton_context_hooks(self, RSpec.configuration.hooks)
+        RSpec.configuration.configure_example(self)
+        RSpec.current_example = self
+
+        start(reporter)
+        Pending.mark_pending!(self, pending) if pending?
+
+        begin
+          if skipped?
+            Pending.mark_pending! self, skip
+          elsif !RSpec.configuration.dry_run?
+            with_around_and_singleton_context_hooks do
+              begin
+                run_before_example
+                @example_group_instance.instance_exec(self, &@example_block)
+
+                if pending?
+                  Pending.mark_fixed! self
+
+                  raise Pending::PendingExampleFixedError,
+                        'Expected example to fail since it is pending, but it passed.',
+                        [location]
+                end
+              rescue Pending::SkipDeclaredInExample
+                # no-op, required metadata has already been set by the `skip`
+                # method.
+              rescue Exception => e
+                set_exception(e)
+              ensure
+                run_after_example
+              end
+            end
+          end
+        rescue Exception => e
+          set_exception(e)
+        ensure
+          ExampleGroup.each_instance_variable_for_example(@example_group_instance) do |ivar|
+            @example_group_instance.instance_variable_set(ivar, nil)
+          end
+          @example_group_instance = nil
+        end
+
+        finish(reporter)
+      ensure
+        RSpec.current_example = nil
+      end
+
+      # Wraps both a `Proc` and an {Example} for use in {Hooks#around
+      # around} hooks. In around hooks we need to yield this special
+      # kind of object (rather than the raw {Example}) because when
+      # there are multiple `around` hooks we have to wrap them recursively.
+      #
+      # @example
+      #
+      #     RSpec.configure do |c|
+      #       c.around do |ex| # Procsy which wraps the example
+      #         if ex.metadata[:key] == :some_value && some_global_condition
+      #           raise "some message"
+      #         end
+      #         ex.run         # run delegates to ex.call.
+      #       end
+      #     end
+      #
+      # @note This class also exposes the instance methods of {Example},
+      #   proxying them through to the wrapped {Example} instance.
+      class Procsy
+        # The {Example} instance.
+        attr_reader :example
+
+        Example.public_instance_methods(false).each do |name|
+          next if name.to_sym == :run || name.to_sym == :inspect
+
+          define_method(name) { |*a, &b| @example.__send__(name, *a, &b) }
+        end
+
+        Proc.public_instance_methods(false).each do |name|
+          next if name.to_sym == :call || name.to_sym == :inspect || name.to_sym == :to_proc
+
+          define_method(name) { |*a, &b| @proc.__send__(name, *a, &b) }
+        end
+
+        # Calls the proc and notes that the example has been executed.
+        def call(*args, &block)
+          @executed = true
+          @proc.call(*args, &block)
+        end
+        alias run call
+
+        # Provides a wrapped proc that will update our `executed?` state when
+        # executed.
+        def to_proc
+          method(:call).to_proc
+        end
+
+        def initialize(example, &block)
+          @example  = example
+          @proc     = block
+          @executed = false
+        end
+
+        # @private
+        def wrap(&block)
+          self.class.new(example, &block)
+        end
+
+        # Indicates whether or not the around hook has executed the example.
+        def executed?
+          @executed
+        end
+
+        # @private
+        def inspect
+          @example.inspect.gsub('Example', 'ExampleProcsy')
+        end
+      end
+
+      # @private
+      #
+      # Used internally to set an exception in an after hook, which
+      # captures the exception but doesn't raise it.
+      def set_exception(exception, context=nil)
+        if pending? && !(Pending::PendingExampleFixedError === exception)
+          execution_result.pending_exception = exception
+        else
+          if @exception
+            # An error has already been set; we don't want to override it,
+            # but we also don't want silence the error, so let's print it.
+            msg = <<-EOS
+
+  An error occurred #{context}
+    #{exception.class}: #{exception.message}
+    occurred at #{exception.backtrace.first}
+
+            EOS
+            RSpec.configuration.reporter.message(msg)
+          end
+
+          @exception ||= exception
+        end
+      end
+
+      # @private
+      #
+      # Used internally to set an exception and fail without actually executing
+      # the example when an exception is raised in before(:context).
+      def fail_with_exception(reporter, exception)
+        start(reporter)
+        set_exception(exception)
+        finish(reporter)
+      end
+
+      # @private
+      #
+      # Used internally to skip without actually executing the example when
+      # skip is used in before(:context).
+      def skip_with_exception(reporter, exception)
+        start(reporter)
+        Pending.mark_skipped! self, exception.argument
+        finish(reporter)
+      end
+
+      # @private
+      def instance_exec_with_rescue(context, &block)
+        @example_group_instance.instance_exec(self, &block)
+      rescue Exception => e
+        set_exception(e, context)
+      end
+
+      # @private
+      def instance_exec(*args, &block)
+        @example_group_instance.instance_exec(*args, &block)
+      end
+
+    private
+
+      def hooks
+        example_group_instance.singleton_class.hooks
+      end
+
+      def with_around_example_hooks
+        hooks.run(:around, :example, self) { yield }
+      rescue Exception => e
+        set_exception(e, "in an `around(:example)` hook")
+      end
+
+      def start(reporter)
+        reporter.example_started(self)
+        execution_result.started_at = clock.now
+      end
+
+      def finish(reporter)
+        pending_message = execution_result.pending_message
+
+        if @exception
+          record_finished :failed
+          execution_result.exception = @exception
+          reporter.example_failed self
+          false
+        elsif pending_message
+          record_finished :pending
+          execution_result.pending_message = pending_message
+          reporter.example_pending self
+          true
+        else
+          record_finished :passed
+          reporter.example_passed self
+          true
+        end
+      end
+
+      def record_finished(status)
+        execution_result.record_finished(status, clock.now)
+      end
+
+      def run_before_example
+        @example_group_instance.setup_mocks_for_rspec
+        hooks.run(:before, :example, self)
+      end
+
+      def with_around_and_singleton_context_hooks
+        singleton_context_hooks_host = example_group_instance.singleton_class
+        singleton_context_hooks_host.run_before_context_hooks(example_group_instance)
+        with_around_example_hooks { yield }
+      ensure
+        singleton_context_hooks_host.run_after_context_hooks(example_group_instance)
+      end
+
+      def run_after_example
+        assign_generated_description if defined?(::RSpec::Matchers)
+        hooks.run(:after, :example, self)
+        verify_mocks
+      ensure
+        @example_group_instance.teardown_mocks_for_rspec
+      end
+
+      def verify_mocks
+        @example_group_instance.verify_mocks_for_rspec if mocks_need_verification?
+      rescue Exception => e
+        if pending?
+          execution_result.pending_fixed = false
+          execution_result.pending_exception = e
+          @exception = nil
+        else
+          set_exception(e)
+        end
+      end
+
+      def mocks_need_verification?
+        exception.nil? || execution_result.pending_fixed?
+      end
+
+      def assign_generated_description
+        if metadata[:description].empty? && (description = generate_description)
+          metadata[:description] = description
+          metadata[:full_description] << description
+        end
+      ensure
+        RSpec::Matchers.clear_generated_description
+      end
+
+      def generate_description
+        RSpec::Matchers.generated_description
+      rescue Exception => e
+        location_description + " (Got an error when generating description " \
+          "from matcher: #{e.class}: #{e.message} -- #{e.backtrace.first})"
+      end
+
+      def location_description
+        "example at #{location}"
+      end
+
+      def skip_message
+        if String === skip
+          skip
+        else
+          Pending::NO_REASON_GIVEN
+        end
+      end
+
+      # Represents the result of executing an example.
+      # Behaves like a hash for backwards compatibility.
+      class ExecutionResult
+        include HashImitatable
+
+        # @return [Symbol] `:passed`, `:failed` or `:pending`.
+        attr_accessor :status
+
+        # @return [Exception, nil] The failure, if there was one.
+        attr_accessor :exception
+
+        # @return [Time] When the example started.
+        attr_accessor :started_at
+
+        # @return [Time] When the example finished.
+        attr_accessor :finished_at
+
+        # @return [Float] How long the example took in seconds.
+        attr_accessor :run_time
+
+        # @return [String, nil] The reason the example was pending,
+        #   or nil if the example was not pending.
+        attr_accessor :pending_message
+
+        # @return [Exception, nil] The exception triggered while
+        #   executing the pending example. If no exception was triggered
+        #   it would no longer get a status of `:pending` unless it was
+        #   tagged with `:skip`.
+        attr_accessor :pending_exception
+
+        # @return [Boolean] For examples tagged with `:pending`,
+        #   this indicates whether or not it now passes.
+        attr_accessor :pending_fixed
+
+        alias pending_fixed? pending_fixed
+
+        # @return [Boolean] Indicates if the example was completely skipped
+        #   (typically done via `:skip` metadata or the `skip` method). Skipped examples
+        #   will have a `:pending` result. A `:pending` result can also come from examples
+        #   that were marked as `:pending`, which causes them to be run, and produces a
+        #   `:failed` result if the example passes.
+        def example_skipped?
+          status == :pending && !pending_exception
+        end
+
+        # @api private
+        # Records the finished status of the example.
+        def record_finished(status, finished_at)
+          self.status      = status
+          self.finished_at = finished_at
+          self.run_time    = (finished_at - started_at).to_f
+        end
+
+      private
+
+        # For backwards compatibility we present `status` as a string
+        # when presenting the legacy hash interface.
+        def hash_for_delegation
+          super.tap do |hash|
+            hash[:status] &&= status.to_s
+          end
+        end
+
+        def set_value(name, value)
+          value &&= value.to_sym if name == :status
+          super(name, value)
+        end
+
+        def get_value(name)
+          if name == :status
+            status.to_s if status
+          else
+            super
+          end
+        end
+
+        def issue_deprecation(_method_name, *_args)
+          RSpec.deprecate("Treating `metadata[:execution_result]` as a hash",
+                          :replacement => "the attributes methods to access the data")
+        end
+      end
+    end
+
+    # @private
+    # Provides an execution context for before/after :suite hooks.
+    class SuiteHookContext < Example
+      def initialize
+        super(AnonymousExampleGroup, "", {})
+      end
+
+      # To ensure we don't silence errors.
+      def set_exception(exception, _context=nil)
+        raise exception
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/example_group.rb b/rspec-core/lib/rspec/core/example_group.rb
new file mode 100644
index 0000000..1738de3
--- /dev/null
+++ b/rspec-core/lib/rspec/core/example_group.rb
@@ -0,0 +1,767 @@
+RSpec::Support.require_rspec_support 'recursive_const_methods'
+
+module RSpec
+  module Core
+    # ExampleGroup and {Example} are the main structural elements of
+    # rspec-core. Consider this example:
+    #
+    #     describe Thing do
+    #       it "does something" do
+    #       end
+    #     end
+    #
+    # The object returned by `describe Thing` is a subclass of ExampleGroup.
+    # The object returned by `it "does something"` is an instance of Example,
+    # which serves as a wrapper for an instance of the ExampleGroup in which it
+    # is declared.
+    #
+    # Example group bodies (e.g. `describe` or `context` blocks) are evaluated
+    # in the context of a new subclass of ExampleGroup. Individual examples are
+    # evaluated in the context of an instance of the specific ExampleGroup
+    # subclass to which they belong.
+    #
+    # Besides the class methods defined here, there are other interesting macros
+    # defined in {Hooks}, {MemoizedHelpers::ClassMethods} and
+    # {SharedExampleGroup}. There are additional instance methods available to
+    # your examples defined in {MemoizedHelpers} and {Pending}.
+    class ExampleGroup
+      extend Hooks
+
+      include MemoizedHelpers
+      extend MemoizedHelpers::ClassMethods
+      include Pending
+      extend SharedExampleGroup
+
+      # @private
+      def self.idempotently_define_singleton_method(name, &definition)
+        (class << self; self; end).module_exec do
+          remove_method(name) if method_defined?(name)
+          define_method(name, &definition)
+        end
+      end
+
+      # @!group Metadata
+
+      # The [Metadata](Metadata) object associated with this group.
+      # @see Metadata
+      def self.metadata
+        @metadata ||= nil
+      end
+
+      # Temporarily replace the provided metadata.
+      # Intended primarily to allow an example group's singleton class
+      # to return the metadata of the example that it exists for. This
+      # is necessary for shared example group inclusion to work properly
+      # with singleton example groups.
+      # @private
+      def self.with_replaced_metadata(meta)
+        orig_metadata = metadata
+        @metadata = meta
+        yield
+      ensure
+        @metadata = orig_metadata
+      end
+
+      # @private
+      # @return [Metadata] belonging to the parent of a nested {ExampleGroup}
+      def self.superclass_metadata
+        @superclass_metadata ||= superclass.respond_to?(:metadata) ? superclass.metadata : nil
+      end
+
+      # @private
+      def self.delegate_to_metadata(*names)
+        names.each do |name|
+          idempotently_define_singleton_method(name) { metadata.fetch(name) }
+        end
+      end
+
+      delegate_to_metadata :described_class, :file_path, :location
+
+      # @return [String] the current example group description
+      def self.description
+        description = metadata[:description]
+        RSpec.configuration.format_docstrings_block.call(description)
+      end
+
+      # Returns the class or module passed to the `describe` method (or alias).
+      # Returns nil if the subject is not a class or module.
+      # @example
+      #     describe Thing do
+      #       it "does something" do
+      #         described_class == Thing
+      #       end
+      #     end
+      #
+      def described_class
+        self.class.described_class
+      end
+
+      # @!endgroup
+
+      # @!group Defining Examples
+
+      # @private
+      # @macro [attach] define_example_method
+      #   @!scope class
+      #   @overload $1
+      #   @overload $1(&example_implementation)
+      #     @param example_implementation [Block] The implementation of the example.
+      #   @overload $1(doc_string, *metadata_keys, metadata={})
+      #     @param doc_string [String] The example's doc string.
+      #     @param metadata [Hash] Metadata for the example.
+      #     @param metadata_keys [Array<Symbol>] Metadata tags for the example.
+      #       Will be transformed into hash entries with `true` values.
+      #   @overload $1(doc_string, *metadata_keys, metadata={}, &example_implementation)
+      #     @param doc_string [String] The example's doc string.
+      #     @param metadata [Hash] Metadata for the example.
+      #     @param metadata_keys [Array<Symbol>] Metadata tags for the example.
+      #       Will be transformed into hash entries with `true` values.
+      #     @param example_implementation [Block] The implementation of the example.
+      #   @yield [Example] the example object
+      #   @example
+      #     $1 do
+      #     end
+      #
+      #     $1 "does something" do
+      #     end
+      #
+      #     $1 "does something", :slow, :uses_js do
+      #     end
+      #
+      #     $1 "does something", :with => 'additional metadata' do
+      #     end
+      #
+      #     $1 "does something" do |ex|
+      #       # ex is the Example object that contains metadata about the example
+      #     end
+      def self.define_example_method(name, extra_options={})
+        idempotently_define_singleton_method(name) do |*all_args, &block|
+          desc, *args = *all_args
+
+          options = Metadata.build_hash_from(args)
+          options.update(:skip => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block
+          options.update(extra_options)
+
+          examples << RSpec::Core::Example.new(self, desc, options, block)
+          examples.last
+        end
+      end
+
+      # Defines an example within a group.
+      define_example_method :example
+      # Defines an example within a group.
+      # This is the primary API to define a code example.
+      define_example_method :it
+      # Defines an example within a group.
+      # Useful for when your docstring does not read well off of `it`.
+      # @example
+      #  RSpec.describe MyClass do
+      #    specify "#do_something is deprecated" do
+      #      # ...
+      #    end
+      #  end
+      define_example_method :specify
+
+      # Shortcut to define an example with `:focus => true`.
+      # @see example
+      define_example_method :focus,    :focus => true
+      # Shortcut to define an example with `:focus => true`.
+      # @see example
+      define_example_method :fexample, :focus => true
+      # Shortcut to define an example with `:focus => true`.
+      # @see example
+      define_example_method :fit,      :focus => true
+      # Shortcut to define an example with `:focus => true`.
+      # @see example
+      define_example_method :fspecify, :focus => true
+      # Shortcut to define an example with `:skip => 'Temporarily skipped with xexample'`.
+      # @see example
+      define_example_method :xexample, :skip => 'Temporarily skipped with xexample'
+      # Shortcut to define an example with `:skip => 'Temporarily skipped with xit'`.
+      # @see example
+      define_example_method :xit,      :skip => 'Temporarily skipped with xit'
+      # Shortcut to define an example with `:skip => 'Temporarily skipped with xspecify'`.
+      # @see example
+      define_example_method :xspecify, :skip => 'Temporarily skipped with xspecify'
+      # Shortcut to define an example with `:skip => true`
+      # @see example
+      define_example_method :skip,     :skip => true
+      # Shortcut to define an example with `:pending => true`
+      # @see example
+      define_example_method :pending,  :pending => true
+
+      # @!endgroup
+
+      # @!group Defining Example Groups
+
+      # @private
+      # @macro [attach] define_example_group_method
+      #   @!scope class
+      #   @overload $1
+      #   @overload $1(&example_group_definition)
+      #     @param example_group_definition [Block] The definition of the example group.
+      #   @overload $1(doc_string, *metadata_keys, metadata={}, &example_implementation)
+      #     @param doc_string [String] The group's doc string.
+      #     @param metadata [Hash] Metadata for the group.
+      #     @param metadata_keys [Array<Symbol>] Metadata tags for the group.
+      #       Will be transformed into hash entries with `true` values.
+      #     @param example_group_definition [Block] The definition of the example group.
+      #
+      #   Generates a subclass of this example group which inherits
+      #   everything except the examples themselves.
+      #
+      #   @example
+      #
+      #     RSpec.describe "something" do # << This describe method is defined in
+      #                                   # << RSpec::Core::DSL, included in the
+      #                                   # << global namespace (optional)
+      #       before do
+      #         do_something_before
+      #       end
+      #
+      #       let(:thing) { Thing.new }
+      #
+      #       $1 "attribute (of something)" do
+      #         # examples in the group get the before hook
+      #         # declared above, and can access `thing`
+      #       end
+      #     end
+      #
+      # @see DSL#describe
+      def self.define_example_group_method(name, metadata={})
+        idempotently_define_singleton_method(name) do |*args, &example_group_block|
+          thread_data = RSpec.thread_local_metadata
+          top_level   = self == ExampleGroup
+
+          if top_level
+            if thread_data[:in_example_group]
+              raise "Creating an isolated context from within a context is " \
+                    "not allowed. Change `RSpec.#{name}` to `#{name}` or " \
+                    "move this to a top-level scope."
+            end
+
+            thread_data[:in_example_group] = true
+          end
+
+          begin
+
+            description = args.shift
+            combined_metadata = metadata.dup
+            combined_metadata.merge!(args.pop) if args.last.is_a? Hash
+            args << combined_metadata
+
+            subclass(self, description, args, &example_group_block).tap do |child|
+              children << child
+            end
+
+          ensure
+            thread_data.delete(:in_example_group) if top_level
+          end
+        end
+
+        RSpec::Core::DSL.expose_example_group_alias(name)
+      end
+
+      define_example_group_method :example_group
+
+      # An alias of `example_group`. Generally used when grouping examples by a
+      # thing you are describing (e.g. an object, class or method).
+      # @see example_group
+      define_example_group_method :describe
+
+      # An alias of `example_group`. Generally used when grouping examples
+      # contextually (e.g. "with xyz", "when xyz" or "if xyz").
+      # @see example_group
+      define_example_group_method :context
+
+      # Shortcut to temporarily make an example group skipped.
+      # @see example_group
+      define_example_group_method :xdescribe, :skip => "Temporarily skipped with xdescribe"
+
+      # Shortcut to temporarily make an example group skipped.
+      # @see example_group
+      define_example_group_method :xcontext,  :skip => "Temporarily skipped with xcontext"
+
+      # Shortcut to define an example group with `:focus => true`.
+      # @see example_group
+      define_example_group_method :fdescribe, :focus => true
+
+      # Shortcut to define an example group with `:focus => true`.
+      # @see example_group
+      define_example_group_method :fcontext,  :focus => true
+
+      # @!endgroup
+
+      # @!group Including Shared Example Groups
+
+      # @private
+      # @macro [attach] define_nested_shared_group_method
+      #   @!scope class
+      #
+      #   @see SharedExampleGroup
+      def self.define_nested_shared_group_method(new_name, report_label="it should behave like")
+        idempotently_define_singleton_method(new_name) do |name, *args, &customization_block|
+          # Pass :caller so the :location metadata is set properly.
+          # Otherwise, it'll be set to the next line because that's
+          # the block's source_location.
+          group = example_group("#{report_label} #{name}", :caller => (the_caller = caller)) do
+            find_and_eval_shared("examples", name, the_caller.first, *args, &customization_block)
+          end
+          group.metadata[:shared_group_name] = name
+          group
+        end
+      end
+
+      # Generates a nested example group and includes the shared content
+      # mapped to `name` in the nested group.
+      define_nested_shared_group_method :it_behaves_like, "behaves like"
+      # Generates a nested example group and includes the shared content
+      # mapped to `name` in the nested group.
+      define_nested_shared_group_method :it_should_behave_like
+
+      # Includes shared content mapped to `name` directly in the group in which
+      # it is declared, as opposed to `it_behaves_like`, which creates a nested
+      # group. If given a block, that block is also eval'd in the current
+      # context.
+      #
+      # @see SharedExampleGroup
+      def self.include_context(name, *args, &block)
+        find_and_eval_shared("context", name, caller.first, *args, &block)
+      end
+
+      # Includes shared content mapped to `name` directly in the group in which
+      # it is declared, as opposed to `it_behaves_like`, which creates a nested
+      # group. If given a block, that block is also eval'd in the current
+      # context.
+      #
+      # @see SharedExampleGroup
+      def self.include_examples(name, *args, &block)
+        find_and_eval_shared("examples", name, caller.first, *args, &block)
+      end
+
+      # @private
+      def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block)
+        shared_block = RSpec.world.shared_example_group_registry.find(parent_groups, name)
+
+        unless shared_block
+          raise ArgumentError, "Could not find shared #{label} #{name.inspect}"
+        end
+
+        SharedExampleGroupInclusionStackFrame.with_frame(name, Metadata.relative_path(inclusion_location)) do
+          module_exec(*args, &shared_block)
+          module_exec(&customization_block) if customization_block
+        end
+      end
+
+      # @!endgroup
+
+      # @private
+      def self.subclass(parent, description, args, &example_group_block)
+        subclass = Class.new(parent)
+        subclass.set_it_up(description, *args, &example_group_block)
+        ExampleGroups.assign_const(subclass)
+        subclass.module_exec(&example_group_block) if example_group_block
+
+        # The LetDefinitions module must be included _after_ other modules
+        # to ensure that it takes precedence when there are name collisions.
+        # Thus, we delay including it until after the example group block
+        # has been eval'd.
+        MemoizedHelpers.define_helpers_on(subclass)
+
+        subclass
+      end
+
+      # @private
+      def self.set_it_up(*args, &example_group_block)
+        # Ruby 1.9 has a bug that can lead to infinite recursion and a
+        # SystemStackError if you include a module in a superclass after
+        # including it in a subclass: https://gist.github.com/845896
+        # To prevent this, we must include any modules in
+        # RSpec::Core::ExampleGroup before users create example groups and have
+        # a chance to include the same module in a subclass of
+        # RSpec::Core::ExampleGroup. So we need to configure example groups
+        # here.
+        ensure_example_groups_are_configured
+
+        description = args.shift
+        user_metadata = Metadata.build_hash_from(args)
+        args.unshift(description)
+
+        @metadata = Metadata::ExampleGroupHash.create(
+          superclass_metadata, user_metadata, *args, &example_group_block
+        )
+
+        hooks.register_globals(self, RSpec.configuration.hooks)
+        RSpec.configuration.configure_group(self)
+      end
+
+      # @private
+      def self.examples
+        @examples ||= []
+      end
+
+      # @private
+      def self.filtered_examples
+        RSpec.world.filtered_examples[self]
+      end
+
+      # @private
+      def self.descendant_filtered_examples
+        @descendant_filtered_examples ||= filtered_examples +
+          FlatMap.flat_map(children, &:descendant_filtered_examples)
+      end
+
+      # @private
+      def self.children
+        @children ||= []
+      end
+
+      # @private
+      def self.descendants
+        @_descendants ||= [self] + FlatMap.flat_map(children, &:descendants)
+      end
+
+      ## @private
+      def self.parent_groups
+        @parent_groups ||= ancestors.select { |a| a < RSpec::Core::ExampleGroup }
+      end
+
+      # @private
+      def self.top_level?
+        @top_level ||= superclass == ExampleGroup
+      end
+
+      # @private
+      def self.ensure_example_groups_are_configured
+        unless defined?(@@example_groups_configured)
+          RSpec.configuration.configure_mock_framework
+          RSpec.configuration.configure_expectation_framework
+          # rubocop:disable Style/ClassVars
+          @@example_groups_configured = true
+          # rubocop:enable Style/ClassVars
+        end
+      end
+
+      # @private
+      def self.before_context_ivars
+        @before_context_ivars ||= {}
+      end
+
+      # @private
+      def self.store_before_context_ivars(example_group_instance)
+        each_instance_variable_for_example(example_group_instance) do |ivar|
+          before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
+        end
+      end
+
+      # @private
+      def self.run_before_context_hooks(example_group_instance)
+        set_ivars(example_group_instance, superclass_before_context_ivars)
+
+        ContextHookMemoizedHash::Before.isolate_for_context_hook(example_group_instance) do
+          hooks.run(:before, :context, example_group_instance)
+        end
+      ensure
+        store_before_context_ivars(example_group_instance)
+      end
+
+      if RUBY_VERSION.to_f >= 1.9
+        # @private
+        def self.superclass_before_context_ivars
+          superclass.before_context_ivars
+        end
+      else # 1.8.7
+        # @private
+        def self.superclass_before_context_ivars
+          if superclass.respond_to?(:before_context_ivars)
+            superclass.before_context_ivars
+          else
+            # `self` must be the singleton class of an ExampleGroup instance.
+            # On 1.8.7, the superclass of a singleton class of an instance of A
+            # is A's singleton class. On 1.9+, it's A. On 1.8.7, the first ancestor
+            # is A, so we can mirror 1.8.7's behavior here. Note that we have to
+            # search for the first that responds to `before_context_ivars`
+            # in case a module has been included in the singleton class.
+            ancestors.find { |a| a.respond_to?(:before_context_ivars) }.before_context_ivars
+          end
+        end
+      end
+
+      # @private
+      def self.run_after_context_hooks(example_group_instance)
+        set_ivars(example_group_instance, before_context_ivars)
+
+        ContextHookMemoizedHash::After.isolate_for_context_hook(example_group_instance) do
+          hooks.run(:after, :context, example_group_instance)
+        end
+      ensure
+        before_context_ivars.clear
+      end
+
+      # Runs all the examples in this group.
+      def self.run(reporter=RSpec::Core::NullReporter.new)
+        if RSpec.world.wants_to_quit
+          RSpec.world.clear_remaining_example_groups if top_level?
+          return
+        end
+        reporter.example_group_started(self)
+
+        should_run_context_hooks = descendant_filtered_examples.any?
+        begin
+          run_before_context_hooks(new('before(:context) hook')) if should_run_context_hooks
+          result_for_this_group = run_examples(reporter)
+          results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all?
+          result_for_this_group && results_for_descendants
+        rescue Pending::SkipDeclaredInExample => ex
+          for_filtered_examples(reporter) { |example| example.skip_with_exception(reporter, ex) }
+        rescue Exception => ex
+          RSpec.world.wants_to_quit = true if fail_fast?
+          for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) }
+        ensure
+          run_after_context_hooks(new('after(:context) hook')) if should_run_context_hooks
+          reporter.example_group_finished(self)
+        end
+      end
+
+      # @private
+      def self.ordering_strategy
+        order = metadata.fetch(:order, :global)
+        registry = RSpec.configuration.ordering_registry
+
+        registry.fetch(order) do
+          warn <<-WARNING.gsub(/^ +\|/, '')
+            |WARNING: Ignoring unknown ordering specified using `:order => #{order.inspect}` metadata.
+            |         Falling back to configured global ordering.
+            |         Unrecognized ordering specified at: #{location}
+          WARNING
+
+          registry.fetch(:global)
+        end
+      end
+
+      # @private
+      def self.run_examples(reporter)
+        ordering_strategy.order(filtered_examples).map do |example|
+          next if RSpec.world.wants_to_quit
+          instance = new(example.inspect_output)
+          set_ivars(instance, before_context_ivars)
+          succeeded = example.run(instance, reporter)
+          RSpec.world.wants_to_quit = true if fail_fast? && !succeeded
+          succeeded
+        end.all?
+      end
+
+      # @private
+      def self.for_filtered_examples(reporter, &block)
+        filtered_examples.each(&block)
+
+        children.each do |child|
+          reporter.example_group_started(child)
+          child.for_filtered_examples(reporter, &block)
+          reporter.example_group_finished(child)
+        end
+        false
+      end
+
+      # @private
+      def self.fail_fast?
+        RSpec.configuration.fail_fast?
+      end
+
+      # @private
+      def self.declaration_line_numbers
+        @declaration_line_numbers ||= [metadata[:line_number]] +
+          examples.map { |e| e.metadata[:line_number] } +
+          FlatMap.flat_map(children, &:declaration_line_numbers)
+      end
+
+      # @private
+      def self.top_level_description
+        parent_groups.last.description
+      end
+
+      # @private
+      def self.set_ivars(instance, ivars)
+        ivars.each { |name, value| instance.instance_variable_set(name, value) }
+      end
+
+      if RUBY_VERSION.to_f < 1.9
+        # @private
+        INSTANCE_VARIABLE_TO_IGNORE = '@__inspect_output'.freeze
+      else
+        # @private
+        INSTANCE_VARIABLE_TO_IGNORE = :@__inspect_output
+      end
+
+      # @private
+      def self.each_instance_variable_for_example(group)
+        group.instance_variables.each do |ivar|
+          yield ivar unless ivar == INSTANCE_VARIABLE_TO_IGNORE
+        end
+      end
+
+      def initialize(inspect_output=nil)
+        @__inspect_output = inspect_output || '(no description provided)'
+      end
+
+      # @private
+      def inspect
+        "#<#{self.class} #{@__inspect_output}>"
+      end
+
+      unless method_defined?(:singleton_class) # for 1.8.7
+        # @private
+        def singleton_class
+          class << self; self; end
+        end
+      end
+
+      # Raised when an RSpec API is called in the wrong scope, such as `before`
+      # being called from within an example rather than from within an example
+      # group block.
+      WrongScopeError = Class.new(NoMethodError)
+
+      def self.method_missing(name, *args)
+        if method_defined?(name)
+          raise WrongScopeError,
+                "`#{name}` is not available on an example group (e.g. a " \
+                "`describe` or `context` block). It is only available from " \
+                "within individual examples (e.g. `it` blocks) or from " \
+                "constructs that run in the scope of an example (e.g. " \
+                "`before`, `let`, etc)."
+        end
+
+        super
+      end
+      private_class_method :method_missing
+
+    private
+
+      def method_missing(name, *args)
+        if self.class.respond_to?(name)
+          raise WrongScopeError,
+                "`#{name}` is not available from within an example (e.g. an " \
+                "`it` block) or from constructs that run in the scope of an " \
+                "example (e.g. `before`, `let`, etc). It is only available " \
+                "on an example group (e.g. a `describe` or `context` block)."
+        end
+
+        super
+      end
+    end
+
+    # @private
+    # Unnamed example group used by `SuiteHookContext`.
+    class AnonymousExampleGroup < ExampleGroup
+      def self.metadata
+        {}
+      end
+    end
+
+    # Contains information about the inclusion site of a shared example group.
+    class SharedExampleGroupInclusionStackFrame
+      # @return [String] the name of the shared example group
+      attr_reader :shared_group_name
+      # @return [String] the location where the shared example was included
+      attr_reader :inclusion_location
+
+      def initialize(shared_group_name, inclusion_location)
+        @shared_group_name  = shared_group_name
+        @inclusion_location = inclusion_location
+      end
+
+      # @return [String] The {#inclusion_location}, formatted for display by a formatter.
+      def formatted_inclusion_location
+        @formatted_inclusion_location ||= begin
+          RSpec.configuration.backtrace_formatter.backtrace_line(
+            inclusion_location.sub(/(:\d+):in .+$/, '\1')
+          )
+        end
+      end
+
+      # @return [String] Description of this stack frame, in the form used by
+      #   RSpec's built-in formatters.
+      def description
+        @description ||= "Shared Example Group: #{shared_group_name.inspect} " \
+          "called from #{formatted_inclusion_location}"
+      end
+
+      # @private
+      def self.current_backtrace
+        RSpec.thread_local_metadata[:shared_example_group_inclusions].reverse
+      end
+
+      # @private
+      def self.with_frame(name, location)
+        current_stack = RSpec.thread_local_metadata[:shared_example_group_inclusions]
+        current_stack << new(name, location)
+        yield
+      ensure
+        current_stack.pop
+      end
+    end
+  end
+
+  # @private
+  #
+  # Namespace for the example group subclasses generated by top-level
+  # `describe`.
+  module ExampleGroups
+    extend Support::RecursiveConstMethods
+
+    def self.assign_const(group)
+      base_name   = base_name_for(group)
+      const_scope = constant_scope_for(group)
+      name        = disambiguate(base_name, const_scope)
+
+      const_scope.const_set(name, group)
+    end
+
+    def self.constant_scope_for(group)
+      const_scope = group.superclass
+      const_scope = self if const_scope == ::RSpec::Core::ExampleGroup
+      const_scope
+    end
+
+    def self.base_name_for(group)
+      return "Anonymous" if group.description.empty?
+
+      # Convert to CamelCase.
+      name = ' ' << group.description
+      name.gsub!(/[^0-9a-zA-Z]+([0-9a-zA-Z])/) do
+        match = ::Regexp.last_match[1]
+        match.upcase!
+        match
+      end
+
+      name.lstrip!                # Remove leading whitespace
+      name.gsub!(/\W/, ''.freeze) # JRuby, RBX and others don't like non-ascii in const names
+
+      # Ruby requires first const letter to be A-Z. Use `Nested`
+      # as necessary to enforce that.
+      name.gsub!(/\A([^A-Z]|\z)/, 'Nested\1'.freeze)
+
+      name
+    end
+
+    if RUBY_VERSION == '1.9.2'
+      class << self
+        alias _base_name_for base_name_for
+        def base_name_for(group)
+          _base_name_for(group) + '_'
+        end
+      end
+      private_class_method :_base_name_for
+    end
+
+    def self.disambiguate(name, const_scope)
+      return name unless const_defined_on?(const_scope, name)
+
+      # Add a trailing number if needed to disambiguate from an existing
+      # constant.
+      name << "_2"
+      name.next! while const_defined_on?(const_scope, name)
+      name
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/filter_manager.rb b/rspec-core/lib/rspec/core/filter_manager.rb
new file mode 100644
index 0000000..1926e72
--- /dev/null
+++ b/rspec-core/lib/rspec/core/filter_manager.rb
@@ -0,0 +1,216 @@
+module RSpec
+  module Core
+    # @private
+    class FilterManager
+      attr_reader :exclusions, :inclusions
+
+      def initialize
+        @exclusions, @inclusions = FilterRules.build
+      end
+
+      # @api private
+      #
+      # @param file_path [String]
+      # @param line_numbers [Array]
+      def add_location(file_path, line_numbers)
+        # locations is a hash of expanded paths to arrays of line
+        # numbers to match against. e.g.
+        #   { "path/to/file.rb" => [37, 42] }
+        locations = inclusions.delete(:locations) || Hash.new { |h, k| h[k] = [] }
+        locations[File.expand_path(file_path)].push(*line_numbers)
+        inclusions.add(:locations => locations)
+      end
+
+      def empty?
+        inclusions.empty? && exclusions.empty?
+      end
+
+      def prune(examples)
+        examples = prune_conditionally_filtered_examples(examples)
+
+        if inclusions.standalone?
+          examples.select { |e| include?(e) }
+        else
+          locations, other_inclusions = inclusions.partition_locations
+
+          examples.select do |e|
+            priority_include?(e, locations) do
+              !exclude?(e) && other_inclusions.include_example?(e)
+            end
+          end
+        end
+      end
+
+      def exclude(*args)
+        exclusions.add(args.last)
+      end
+
+      def exclude_only(*args)
+        exclusions.use_only(args.last)
+      end
+
+      def exclude_with_low_priority(*args)
+        exclusions.add_with_low_priority(args.last)
+      end
+
+      def include(*args)
+        inclusions.add(args.last)
+      end
+
+      def include_only(*args)
+        inclusions.use_only(args.last)
+      end
+
+      def include_with_low_priority(*args)
+        inclusions.add_with_low_priority(args.last)
+      end
+
+    private
+
+      def exclude?(example)
+        exclusions.include_example?(example)
+      end
+
+      def include?(example)
+        inclusions.include_example?(example)
+      end
+
+      def prune_conditionally_filtered_examples(examples)
+        examples.reject do |ex|
+          meta = ex.metadata
+          !meta.fetch(:if, true) || meta[:unless]
+        end
+      end
+
+      # When a user specifies a particular spec location, that takes priority
+      # over any exclusion filters (such as if the spec is tagged with `:slow`
+      # and there is a `:slow => true` exclusion filter), but only for specs
+      # defined in the same file as the location filters. Excluded specs in
+      # other files should still be excluded.
+      def priority_include?(example, locations)
+        return yield if locations[example.metadata[:absolute_file_path]].empty?
+        MetadataFilter.filter_applies?(:locations, locations, example.metadata)
+      end
+    end
+
+    # @private
+    class FilterRules
+      PROC_HEX_NUMBER = /0x[0-9a-f]+@/
+      PROJECT_DIR = File.expand_path('.')
+
+      attr_accessor :opposite
+      attr_reader :rules
+
+      def self.build
+        exclusions = ExclusionRules.new
+        inclusions = InclusionRules.new
+        exclusions.opposite = inclusions
+        inclusions.opposite = exclusions
+        [exclusions, inclusions]
+      end
+
+      def initialize(rules={})
+        @rules = rules
+      end
+
+      def add(updated)
+        @rules.merge!(updated).each_key { |k| opposite.delete(k) }
+      end
+
+      def add_with_low_priority(updated)
+        updated = updated.merge(@rules)
+        opposite.each_pair { |k, v| updated.delete(k) if updated[k] == v }
+        @rules.replace(updated)
+      end
+
+      def use_only(updated)
+        updated.each_key { |k| opposite.delete(k) }
+        @rules.replace(updated)
+      end
+
+      def clear
+        @rules.clear
+      end
+
+      def delete(key)
+        @rules.delete(key)
+      end
+
+      def fetch(*args, &block)
+        @rules.fetch(*args, &block)
+      end
+
+      def [](key)
+        @rules[key]
+      end
+
+      def empty?
+        rules.empty?
+      end
+
+      def each_pair(&block)
+        @rules.each_pair(&block)
+      end
+
+      def description
+        rules.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)', '')
+      end
+
+      def include_example?(example)
+        MetadataFilter.apply?(:any?, @rules, example.metadata)
+      end
+    end
+
+    # @private
+    ExclusionRules = FilterRules
+
+    # @private
+    class InclusionRules < FilterRules
+      def add(*args)
+        apply_standalone_filter(*args) || super
+      end
+
+      def add_with_low_priority(*args)
+        apply_standalone_filter(*args) || super
+      end
+
+      def use(*args)
+        apply_standalone_filter(*args) || super
+      end
+
+      def partition_locations
+        locations = @rules.fetch(:locations) { Hash.new([]) }
+        other_inclusions = self.class.new(@rules.dup.tap { |r| r.delete(:locations) })
+
+        return locations, other_inclusions
+      end
+
+      def include_example?(example)
+        @rules.empty? || super
+      end
+
+      def standalone?
+        is_standalone_filter?(@rules)
+      end
+
+    private
+
+      def apply_standalone_filter(updated)
+        return true if standalone?
+        return nil unless is_standalone_filter?(updated)
+
+        replace_filters(updated)
+        true
+      end
+
+      def replace_filters(new_rules)
+        @rules.replace(new_rules)
+        opposite.clear
+      end
+
+      def is_standalone_filter?(rules)
+        rules.key?(:full_description)
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/flat_map.rb b/rspec-core/lib/rspec/core/flat_map.rb
new file mode 100644
index 0000000..71093ac
--- /dev/null
+++ b/rspec-core/lib/rspec/core/flat_map.rb
@@ -0,0 +1,18 @@
+module RSpec
+  module Core
+    # @private
+    module FlatMap
+      if [].respond_to?(:flat_map)
+        def flat_map(array, &block)
+          array.flat_map(&block)
+        end
+      else # for 1.8.7
+        def flat_map(array, &block)
+          array.map(&block).flatten(1)
+        end
+      end
+
+      module_function :flat_map
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters.rb b/rspec-core/lib/rspec/core/formatters.rb
new file mode 100644
index 0000000..765c2e1
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters.rb
@@ -0,0 +1,244 @@
+RSpec::Support.require_rspec_support "directory_maker"
+# ## Built-in Formatters
+#
+# * progress (default) - Prints dots for passing examples, `F` for failures, `*`
+#                        for pending.
+# * documentation - Prints the docstrings passed to `describe` and `it` methods
+#                   (and their aliases).
+# * html
+# * json - Useful for archiving data for subsequent analysis.
+#
+# The progress formatter is the default, but you can choose any one or more of
+# the other formatters by passing with the `--format` (or `-f` for short)
+# command-line option, e.g.
+#
+#     rspec --format documentation
+#
+# You can also send the output of multiple formatters to different streams, e.g.
+#
+#     rspec --format documentation --format html --out results.html
+#
+# This example sends the output of the documentation formatter to `$stdout`, and
+# the output of the html formatter to results.html.
+#
+# ## Custom Formatters
+#
+# You can tell RSpec to use a custom formatter by passing its path and name to
+# the `rspec` commmand. For example, if you define MyCustomFormatter in
+# path/to/my_custom_formatter.rb, you would type this command:
+#
+#     rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter
+#
+# The reporter calls every formatter with this protocol:
+#
+# * To start
+#   * `start(StartNotification)`
+# * Once per example group
+#   * `example_group_started(GroupNotification)`
+# * Once per example
+#   * `example_started(ExampleNotification)`
+# * One of these per example, depending on outcome
+#   * `example_passed(ExampleNotification)`
+#   * `example_failed(FailedExampleNotification)`
+#   * `example_pending(ExampleNotification)`
+# * Optionally at any time
+#   * `message(MessageNotification)`
+# * At the end of the suite
+#   * `stop(ExamplesNotification)`
+#   * `start_dump(NullNotification)`
+#   * `dump_pending(ExamplesNotification)`
+#   * `dump_failures(ExamplesNotification)`
+#   * `dump_summary(SummaryNotification)`
+#   * `seed(SeedNotification)`
+#   * `close(NullNotification)`
+#
+# Only the notifications to which you subscribe your formatter will be called
+# on your formatter. To subscribe your formatter use:
+# `RSpec::Core::Formatters#register` e.g.
+#
+# `RSpec::Core::Formatters.register FormatterClassName, :example_passed, :example_failed`
+#
+# We recommend you implement the methods yourself; for simplicity we provide the
+# default formatter output via our notification objects but if you prefer you
+# can subclass `RSpec::Core::Formatters::BaseTextFormatter` and override the
+# methods you wish to enhance.
+#
+# @see RSpec::Core::Formatters::BaseTextFormatter
+# @see RSpec::Core::Reporter
+module RSpec::Core::Formatters
+  autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
+  autoload :HtmlFormatter,          'rspec/core/formatters/html_formatter'
+  autoload :ProgressFormatter,      'rspec/core/formatters/progress_formatter'
+  autoload :ProfileFormatter,       'rspec/core/formatters/profile_formatter'
+  autoload :JsonFormatter,          'rspec/core/formatters/json_formatter'
+
+  # Register the formatter class
+  # @param formatter_class [Class] formatter class to register
+  # @param notifications [Symbol, ...] one or more notifications to be
+  #   registered to the specified formatter
+  #
+  # @see RSpec::Core::Formatters::BaseFormatter
+  def self.register(formatter_class, *notifications)
+    Loader.formatters[formatter_class] = notifications
+  end
+
+  # @api private
+  #
+  # `RSpec::Core::Formatters::Loader` is an internal class for
+  # managing formatters used by a particular configuration. It is
+  # not expected to be used directly, but only through the configuration
+  # interface.
+  class Loader
+    # @api private
+    #
+    # Internal formatters are stored here when loaded.
+    def self.formatters
+      @formatters ||= {}
+    end
+
+    # @api private
+    def initialize(reporter)
+      @formatters = []
+      @reporter = reporter
+      self.default_formatter = 'progress'
+    end
+
+    # @return [Array] the loaded formatters
+    attr_reader :formatters
+
+    # @return [Reporter] the reporter
+    attr_reader :reporter
+
+    # @return [String] the default formatter to setup, defaults to `progress`
+    attr_accessor :default_formatter
+
+    # @private
+    def setup_default(output_stream, deprecation_stream)
+      add default_formatter, output_stream if @formatters.empty?
+
+      unless @formatters.any? { |formatter| DeprecationFormatter === formatter }
+        add DeprecationFormatter, deprecation_stream, output_stream
+      end
+
+      return unless RSpec.configuration.profile_examples? && !existing_formatter_implements?(:dump_profile)
+
+      add RSpec::Core::Formatters::ProfileFormatter, output_stream
+    end
+
+    # @private
+    def add(formatter_to_use, *paths)
+      formatter_class = find_formatter(formatter_to_use)
+
+      args = paths.map { |p| p.respond_to?(:puts) ? p : file_at(p) }
+
+      if !Loader.formatters[formatter_class].nil?
+        formatter = formatter_class.new(*args)
+        @reporter.register_listener formatter, *notifications_for(formatter_class)
+      elsif defined?(RSpec::LegacyFormatters)
+        formatter = RSpec::LegacyFormatters.load_formatter formatter_class, *args
+        @reporter.register_listener formatter, *formatter.notifications
+      else
+        line = ::RSpec::CallerFilter.first_non_rspec_line
+        if line
+          call_site = "Formatter added at: #{line}"
+        else
+          call_site = "The formatter was added via command line flag or your "\
+                      "`.rspec` file."
+        end
+
+        RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/, ' ')
+          |The #{formatter_class} formatter uses the deprecated formatter
+          |interface not supported directly by RSpec 3.
+          |
+          |To continue to use this formatter you must install the
+          |`rspec-legacy_formatters` gem, which provides support
+          |for legacy formatters or upgrade the formatter to a
+          |compatible version.
+          |
+          |#{call_site}
+        WARNING
+        return
+      end
+      @formatters << formatter unless duplicate_formatter_exists?(formatter)
+      formatter
+    end
+
+  private
+
+    def find_formatter(formatter_to_use)
+      built_in_formatter(formatter_to_use) ||
+      custom_formatter(formatter_to_use)   ||
+      (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - " \
+                            "maybe you meant 'documentation' or 'progress'?.")
+    end
+
+    def duplicate_formatter_exists?(new_formatter)
+      @formatters.any? do |formatter|
+        formatter.class === new_formatter && formatter.output == new_formatter.output
+      end
+    end
+
+    def existing_formatter_implements?(notification)
+      @reporter.registered_listeners(notification).any?
+    end
+
+    def built_in_formatter(key)
+      case key.to_s
+      when 'd', 'doc', 'documentation'
+        DocumentationFormatter
+      when 'h', 'html'
+        HtmlFormatter
+      when 'p', 'progress'
+        ProgressFormatter
+      when 'j', 'json'
+        JsonFormatter
+      end
+    end
+
+    def notifications_for(formatter_class)
+      formatter_class.ancestors.inject(Set.new) do |notifications, klass|
+        notifications + Loader.formatters.fetch(klass) { Set.new }
+      end
+    end
+
+    def custom_formatter(formatter_ref)
+      if Class === formatter_ref
+        formatter_ref
+      elsif string_const?(formatter_ref)
+        begin
+          formatter_ref.gsub(/^::/, '').split('::').inject(Object) { |a, e| a.const_get e }
+        rescue NameError
+          require(path_for(formatter_ref)) ? retry : raise
+        end
+      end
+    end
+
+    def string_const?(str)
+      str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
+    end
+
+    def path_for(const_ref)
+      underscore_with_fix_for_non_standard_rspec_naming(const_ref)
+    end
+
+    def underscore_with_fix_for_non_standard_rspec_naming(string)
+      underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
+    end
+
+    # activesupport/lib/active_support/inflector/methods.rb, line 48
+    def underscore(camel_cased_word)
+      word = camel_cased_word.to_s.dup
+      word.gsub!(/::/, '/')
+      word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
+      word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
+      word.tr!("-", "_")
+      word.downcase!
+      word
+    end
+
+    def file_at(path)
+      RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path))
+      File.new(path, 'w')
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/base_formatter.rb b/rspec-core/lib/rspec/core/formatters/base_formatter.rb
new file mode 100644
index 0000000..84248aa
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/base_formatter.rb
@@ -0,0 +1,70 @@
+RSpec::Support.require_rspec_core "formatters/helpers"
+require 'stringio'
+
+module RSpec
+  module Core
+    module Formatters
+      # RSpec's built-in formatters are all subclasses of
+      # RSpec::Core::Formatters::BaseTextFormatter.
+      #
+      # @see RSpec::Core::Formatters::BaseTextFormatter
+      # @see RSpec::Core::Reporter
+      # @see RSpec::Core::Formatters::Protocol
+      class BaseFormatter
+        # All formatters inheriting from this formatter will receive these
+        # notifications.
+        Formatters.register self, :start, :example_group_started, :close
+        attr_accessor :example_group
+        attr_reader :output
+
+        # @api public
+        # @param output [IO] the formatter output
+        # @see RSpec::Core::Formatters::Protocol#initialize
+        def initialize(output)
+          @output = output || StringIO.new
+          @example_group = nil
+        end
+
+        # @api public
+        #
+        # @param notification [StartNotification]
+        # @see RSpec::Core::Formatters::Protocol#start
+        def start(notification)
+          start_sync_output
+          @example_count = notification.count
+        end
+
+        # @api public
+        #
+        # @param notification [GroupNotification] containing example_group
+        #   subclass of `RSpec::Core::ExampleGroup`
+        # @see RSpec::Core::Formatters::Protocol#example_group_started
+        def example_group_started(notification)
+          @example_group = notification.group
+        end
+
+        # @api public
+        #
+        # @param _notification [NullNotification] (Ignored)
+        # @see RSpec::Core::Formatters::Protocol#close
+        def close(_notification)
+          restore_sync_output
+        end
+
+      private
+
+        def start_sync_output
+          @old_sync, output.sync = output.sync, true if output_supports_sync
+        end
+
+        def restore_sync_output
+          output.sync = @old_sync if output_supports_sync && !output.closed?
+        end
+
+        def output_supports_sync
+          output.respond_to?(:sync=)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/base_text_formatter.rb b/rspec-core/lib/rspec/core/formatters/base_text_formatter.rb
new file mode 100644
index 0000000..03b79fb
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/base_text_formatter.rb
@@ -0,0 +1,76 @@
+RSpec::Support.require_rspec_core "formatters/base_formatter"
+RSpec::Support.require_rspec_core "formatters/console_codes"
+
+module RSpec
+  module Core
+    module Formatters
+      # Base for all of RSpec's built-in formatters. See
+      # RSpec::Core::Formatters::BaseFormatter to learn more about all of the
+      # methods called by the reporter.
+      #
+      # @see RSpec::Core::Formatters::BaseFormatter
+      # @see RSpec::Core::Reporter
+      class BaseTextFormatter < BaseFormatter
+        Formatters.register self,
+                            :message, :dump_summary, :dump_failures, :dump_pending, :seed
+
+        # @api public
+        #
+        # Used by the reporter to send messages to the output stream.
+        #
+        # @param notification [MessageNotification] containing message
+        def message(notification)
+          output.puts notification.message
+        end
+
+        # @api public
+        #
+        # Dumps detailed information about each example failure.
+        #
+        # @param notification [NullNotification]
+        def dump_failures(notification)
+          return if notification.failure_notifications.empty?
+          output.puts notification.fully_formatted_failed_examples
+        end
+
+        # @api public
+        #
+        # This method is invoked after the dumping of examples and failures.
+        # Each parameter is assigned to a corresponding attribute.
+        #
+        # @param summary [SummaryNotification] containing duration,
+        #   example_count, failure_count and pending_count
+        def dump_summary(summary)
+          output.puts summary.fully_formatted
+        end
+
+        # @private
+        def dump_pending(notification)
+          return if notification.pending_examples.empty?
+          output.puts notification.fully_formatted_pending_examples
+        end
+
+        # @private
+        def seed(notification)
+          return unless notification.seed_used?
+          output.puts notification.fully_formatted
+        end
+
+        # @api public
+        #
+        # Invoked at the very end, `close` allows the formatter to clean
+        # up resources, e.g. open streams, etc.
+        #
+        # @param _notification [NullNotification] (Ignored)
+        def close(_notification)
+          return unless IO === output
+          return if output.closed?
+
+          output.puts
+
+          output.close unless output == $stdout
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/console_codes.rb b/rspec-core/lib/rspec/core/formatters/console_codes.rb
new file mode 100644
index 0000000..1419dbc
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/console_codes.rb
@@ -0,0 +1,65 @@
+module RSpec
+  module Core
+    module Formatters
+      # ConsoleCodes provides helpers for formatting console output
+      # with ANSI codes, e.g. color's and bold.
+      module ConsoleCodes
+        # @private
+        VT100_CODES =
+          {
+            :black   => 30,
+            :red     => 31,
+            :green   => 32,
+            :yellow  => 33,
+            :blue    => 34,
+            :magenta => 35,
+            :cyan    => 36,
+            :white   => 37,
+            :bold    => 1,
+          }
+        # @private
+        VT100_CODE_VALUES = VT100_CODES.invert
+
+        module_function
+
+        # @private
+        CONFIG_COLORS_TO_METHODS = Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method|
+          hash[method.to_s.sub(/_color\z/, '').to_sym] = method
+          hash
+        end
+
+        # Fetches the correct code for the supplied symbol, or checks
+        # that a code is valid. Defaults to white (37).
+        #
+        # @param code_or_symbol [Symbol, Fixnum] Symbol or code to check
+        # @return [Fixnum] a console code
+        def console_code_for(code_or_symbol)
+          if (config_method = CONFIG_COLORS_TO_METHODS[code_or_symbol])
+            console_code_for RSpec.configuration.__send__(config_method)
+          elsif VT100_CODE_VALUES.key?(code_or_symbol)
+            code_or_symbol
+          else
+            VT100_CODES.fetch(code_or_symbol) do
+              console_code_for(:white)
+            end
+          end
+        end
+
+        # Wraps a piece of text in ANSI codes with the supplied code. Will
+        # only apply the control code if `RSpec.configuration.color_enabled?`
+        # returns true.
+        #
+        # @param text [String] the text to wrap
+        # @param code_or_symbol [Symbol, Fixnum] the desired control code
+        # @return [String] the wrapped text
+        def wrap(text, code_or_symbol)
+          if RSpec.configuration.color_enabled?
+            "\e[#{console_code_for(code_or_symbol)}m#{text}\e[0m"
+          else
+            text
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/deprecation_formatter.rb b/rspec-core/lib/rspec/core/formatters/deprecation_formatter.rb
new file mode 100644
index 0000000..118fe88
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/deprecation_formatter.rb
@@ -0,0 +1,224 @@
+RSpec::Support.require_rspec_core "formatters/helpers"
+require 'set'
+
+module RSpec
+  module Core
+    module Formatters
+      # @private
+      class DeprecationFormatter
+        Formatters.register self, :deprecation, :deprecation_summary
+
+        attr_reader :count, :deprecation_stream, :summary_stream
+
+        def initialize(deprecation_stream, summary_stream)
+          @deprecation_stream = deprecation_stream
+          @summary_stream = summary_stream
+          @seen_deprecations = Set.new
+          @count = 0
+        end
+        alias :output :deprecation_stream
+
+        def printer
+          @printer ||= case deprecation_stream
+                       when File
+                         ImmediatePrinter.new(FileStream.new(deprecation_stream),
+                                              summary_stream, self)
+                       when RaiseErrorStream
+                         ImmediatePrinter.new(deprecation_stream, summary_stream, self)
+                       else
+                         DelayedPrinter.new(deprecation_stream, summary_stream, self)
+                       end
+        end
+
+        def deprecation(notification)
+          return if @seen_deprecations.include? notification
+
+          @count += 1
+          printer.print_deprecation_message notification
+          @seen_deprecations << notification
+        end
+
+        def deprecation_summary(_notification)
+          printer.deprecation_summary
+        end
+
+        def deprecation_message_for(data)
+          if data.message
+            SpecifiedDeprecationMessage.new(data)
+          else
+            GeneratedDeprecationMessage.new(data)
+          end
+        end
+
+        RAISE_ERROR_CONFIG_NOTICE = <<-EOS.gsub(/^\s+\|/, '')
+          |
+          |If you need more of the backtrace for any of these deprecations to
+          |identify where to make the necessary changes, you can configure
+          |`config.raise_errors_for_deprecations!`, and it will turn the
+          |deprecation warnings into errors, giving you the full backtrace.
+        EOS
+
+        DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " \
+          "`config.deprecation_stream` to a file for full output."
+
+        SpecifiedDeprecationMessage = Struct.new(:type) do
+          def initialize(data)
+            @message = data.message
+            super deprecation_type_for(data)
+          end
+
+          def to_s
+            output_formatted @message
+          end
+
+          def too_many_warnings_message
+            msg = "Too many similar deprecation messages reported, disregarding further reports. "
+            msg << DEPRECATION_STREAM_NOTICE
+            msg
+          end
+
+          private
+
+          def output_formatted(str)
+            return str unless str.lines.count > 1
+            separator = "#{'-' * 80}"
+            "#{separator}\n#{str.chomp}\n#{separator}"
+          end
+
+          def deprecation_type_for(data)
+            data.message.gsub(/(\w+\/)+\w+\.rb:\d+/, '')
+          end
+        end
+
+        GeneratedDeprecationMessage = Struct.new(:type) do
+          def initialize(data)
+            @data = data
+            super data.deprecated
+          end
+
+          def to_s
+            msg =  "#{@data.deprecated} is deprecated."
+            msg << " Use #{@data.replacement} instead." if @data.replacement
+            msg << " Called from #{@data.call_site}." if @data.call_site
+            msg
+          end
+
+          def too_many_warnings_message
+            msg = "Too many uses of deprecated '#{type}'. "
+            msg << DEPRECATION_STREAM_NOTICE
+            msg
+          end
+        end
+
+        # @private
+        class ImmediatePrinter
+          attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter
+
+          def initialize(deprecation_stream, summary_stream, deprecation_formatter)
+            @deprecation_stream = deprecation_stream
+
+            @summary_stream = summary_stream
+            @deprecation_formatter = deprecation_formatter
+          end
+
+          def print_deprecation_message(data)
+            deprecation_message = deprecation_formatter.deprecation_message_for(data)
+            deprecation_stream.puts deprecation_message.to_s
+          end
+
+          def deprecation_summary
+            return if deprecation_formatter.count.zero?
+            deprecation_stream.summarize(summary_stream, deprecation_formatter.count)
+          end
+        end
+
+        # @private
+        class DelayedPrinter
+          TOO_MANY_USES_LIMIT = 4
+
+          attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter
+
+          def initialize(deprecation_stream, summary_stream, deprecation_formatter)
+            @deprecation_stream = deprecation_stream
+            @summary_stream = summary_stream
+            @deprecation_formatter = deprecation_formatter
+            @seen_deprecations = Hash.new { 0 }
+            @deprecation_messages = Hash.new { |h, k| h[k] = [] }
+          end
+
+          def print_deprecation_message(data)
+            deprecation_message = deprecation_formatter.deprecation_message_for(data)
+            @seen_deprecations[deprecation_message] += 1
+
+            stash_deprecation_message(deprecation_message)
+          end
+
+          def stash_deprecation_message(deprecation_message)
+            if @seen_deprecations[deprecation_message] < TOO_MANY_USES_LIMIT
+              @deprecation_messages[deprecation_message] << deprecation_message.to_s
+            elsif @seen_deprecations[deprecation_message] == TOO_MANY_USES_LIMIT
+              @deprecation_messages[deprecation_message] << deprecation_message.too_many_warnings_message
+            end
+          end
+
+          def deprecation_summary
+            return unless @deprecation_messages.any?
+
+            print_deferred_deprecation_warnings
+            deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE
+
+            summary_stream.puts "\n#{Helpers.pluralize(deprecation_formatter.count, 'deprecation warning')} total"
+          end
+
+          def print_deferred_deprecation_warnings
+            deprecation_stream.puts "\nDeprecation Warnings:\n\n"
+            @deprecation_messages.keys.sort_by(&:type).each do |deprecation|
+              messages = @deprecation_messages[deprecation]
+              messages.each { |msg| deprecation_stream.puts msg }
+              deprecation_stream.puts
+            end
+          end
+        end
+
+        # @private
+        # Not really a stream, but is usable in place of one.
+        class RaiseErrorStream
+          def puts(message)
+            raise DeprecationError, message
+          end
+
+          def summarize(summary_stream, deprecation_count)
+            summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} found."
+          end
+        end
+
+        # @private
+        # Wraps a File object and provides file-specific operations.
+        class FileStream
+          def initialize(file)
+            @file = file
+
+            # In one of my test suites, I got lots of duplicate output in the
+            # deprecation file (e.g. 200 of the same deprecation, even though
+            # the `puts` below was only called 6 times). Setting `sync = true`
+            # fixes this (but we really have no idea why!).
+            @file.sync = true
+          end
+
+          def puts(*args)
+            @file.puts(*args)
+          end
+
+          def summarize(summary_stream, deprecation_count)
+            path = @file.respond_to?(:path) ? @file.path : @file.inspect
+            summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} logged to #{path}"
+            puts RAISE_ERROR_CONFIG_NOTICE
+          end
+        end
+      end
+    end
+
+    # Deprecation Error.
+    DeprecationError = Class.new(StandardError)
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/documentation_formatter.rb b/rspec-core/lib/rspec/core/formatters/documentation_formatter.rb
new file mode 100644
index 0000000..5deb4a7
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/documentation_formatter.rb
@@ -0,0 +1,74 @@
+RSpec::Support.require_rspec_core "formatters/base_text_formatter"
+
+module RSpec
+  module Core
+    module Formatters
+      # @private
+      class DocumentationFormatter < BaseTextFormatter
+        Formatters.register self, :example_group_started, :example_group_finished,
+                            :example_passed, :example_pending, :example_failed
+
+        def initialize(output)
+          super
+          @group_level = 0
+        end
+
+        def example_group_started(notification)
+          output.puts if @group_level == 0
+          output.puts "#{current_indentation}#{notification.group.description.strip}"
+
+          @group_level += 1
+        end
+
+        def example_group_finished(_notification)
+          @group_level -= 1
+        end
+
+        def example_passed(passed)
+          output.puts passed_output(passed.example)
+        end
+
+        def example_pending(pending)
+          output.puts pending_output(pending.example,
+                                     pending.example.execution_result.pending_message)
+        end
+
+        def example_failed(failure)
+          output.puts failure_output(failure.example,
+                                     failure.example.execution_result.exception)
+        end
+
+      private
+
+        def passed_output(example)
+          ConsoleCodes.wrap("#{current_indentation}#{example.description.strip}", :success)
+        end
+
+        def pending_output(example, message)
+          ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \
+                            "(PENDING: #{message})",
+                            :pending)
+        end
+
+        def failure_output(example, _exception)
+          ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \
+                            "(FAILED - #{next_failure_index})",
+                            :failure)
+        end
+
+        def next_failure_index
+          @next_failure_index ||= 0
+          @next_failure_index += 1
+        end
+
+        def current_indentation
+          '  ' * @group_level
+        end
+
+        def example_group_chain
+          example_group.parent_groups.reverse
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/helpers.rb b/rspec-core/lib/rspec/core/formatters/helpers.rb
new file mode 100644
index 0000000..f6acca2
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/helpers.rb
@@ -0,0 +1,89 @@
+module RSpec
+  module Core
+    module Formatters
+      # Formatters helpers.
+      module Helpers
+        # @private
+        SUB_SECOND_PRECISION = 5
+
+        # @private
+        DEFAULT_PRECISION = 2
+
+        # @api private
+        #
+        # Formats seconds into a human-readable string.
+        #
+        # @param duration [Float, Fixnum] in seconds
+        # @return [String] human-readable time
+        #
+        # @example
+        #    format_duration(1) #=>  "1 minute 1 second"
+        #    format_duration(135.14) #=> "2 minutes 15.14 seconds"
+        def self.format_duration(duration)
+          precision = case
+                      when duration < 1 then    SUB_SECOND_PRECISION
+                      when duration < 120 then  DEFAULT_PRECISION
+                      when duration < 300 then  1
+                      else                  0
+                      end
+
+          if duration > 60
+            minutes = (duration.to_i / 60).to_i
+            seconds = duration - minutes * 60
+
+            "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds, precision), 'second')}"
+          else
+            pluralize(format_seconds(duration, precision), 'second')
+          end
+        end
+
+        # @api private
+        #
+        # Formats seconds to have 5 digits of precision with trailing zeros
+        # removed if the number is less than 1 or with 2 digits of precision if
+        # the number is greater than zero.
+        #
+        # @param float [Float]
+        # @return [String] formatted float
+        #
+        # @example
+        #    format_seconds(0.000006) #=> "0.00001"
+        #    format_seconds(0.020000) #=> "0.02"
+        #    format_seconds(1.00000000001) #=> "1"
+        #
+        # The precision used is set in {Helpers::SUB_SECOND_PRECISION} and
+        # {Helpers::DEFAULT_PRECISION}.
+        #
+        # @see #strip_trailing_zeroes
+        def self.format_seconds(float, precision=nil)
+          precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION
+          formatted = "%.#{precision}f" % float
+          strip_trailing_zeroes(formatted)
+        end
+
+        # @api private
+        #
+        # Remove trailing zeros from a string.
+        #
+        # @param string [String] string with trailing zeros
+        # @return [String] string with trailing zeros removed
+        def self.strip_trailing_zeroes(string)
+          stripped = string.sub(/[^1-9]+$/, '')
+          stripped.empty? ? "0" : stripped
+        end
+        private_class_method :strip_trailing_zeroes
+
+        # @api private
+        #
+        # Pluralize a word based on a count.
+        #
+        # @param count [Fixnum] number of objects
+        # @param string [String] word to be pluralized
+        # @return [String] pluralized word
+        def self.pluralize(count, string)
+          "#{count} #{string}#{'s' unless count.to_f == 1}"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/html_formatter.rb b/rspec-core/lib/rspec/core/formatters/html_formatter.rb
new file mode 100644
index 0000000..30868b4
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/html_formatter.rb
@@ -0,0 +1,154 @@
+RSpec::Support.require_rspec_core "formatters/base_text_formatter"
+RSpec::Support.require_rspec_core "formatters/html_printer"
+
+module RSpec
+  module Core
+    module Formatters
+      # @private
+      class HtmlFormatter < BaseFormatter
+        Formatters.register self, :start, :example_group_started, :start_dump,
+                            :example_started, :example_passed, :example_failed,
+                            :example_pending, :dump_summary
+
+        def initialize(output)
+          super(output)
+          @failed_examples = []
+          @example_group_number = 0
+          @example_number = 0
+          @header_red = nil
+          @printer = HtmlPrinter.new(output)
+        end
+
+        def start(notification)
+          super
+          @printer.print_html_start
+          @printer.flush
+        end
+
+        def example_group_started(notification)
+          super
+          @example_group_red = false
+          @example_group_number += 1
+
+          @printer.print_example_group_end unless example_group_number == 1
+          @printer.print_example_group_start(example_group_number,
+                                             notification.group.description,
+                                             notification.group.parent_groups.size)
+          @printer.flush
+        end
+
+        def start_dump(_notification)
+          @printer.print_example_group_end
+          @printer.flush
+        end
+
+        def example_started(_notification)
+          @example_number += 1
+        end
+
+        def example_passed(passed)
+          @printer.move_progress(percent_done)
+          @printer.print_example_passed(passed.example.description, passed.example.execution_result.run_time)
+          @printer.flush
+        end
+
+        def example_failed(failure)
+          @failed_examples << failure.example
+          unless @header_red
+            @header_red = true
+            @printer.make_header_red
+          end
+
+          unless @example_group_red
+            @example_group_red = true
+            @printer.make_example_group_header_red(example_group_number)
+          end
+
+          @printer.move_progress(percent_done)
+
+          example = failure.example
+
+          exception = failure.exception
+          exception_details = if exception
+                                {
+                                  :message => exception.message,
+                                  :backtrace => failure.formatted_backtrace.join("\n")
+                                }
+                              else
+                                false
+                              end
+          extra = extra_failure_content(failure)
+
+          @printer.print_example_failed(
+            example.execution_result.pending_fixed,
+            example.description,
+            example.execution_result.run_time,
+            @failed_examples.size,
+            exception_details,
+            (extra == "") ? false : extra,
+            true
+          )
+          @printer.flush
+        end
+
+        def example_pending(pending)
+          example = pending.example
+
+          @printer.make_header_yellow unless @header_red
+          @printer.make_example_group_header_yellow(example_group_number) unless @example_group_red
+          @printer.move_progress(percent_done)
+          @printer.print_example_pending(example.description, example.execution_result.pending_message)
+          @printer.flush
+        end
+
+        def dump_summary(summary)
+          @printer.print_summary(
+            summary.duration,
+            summary.example_count,
+            summary.failure_count,
+            summary.pending_count
+          )
+          @printer.flush
+        end
+
+      private
+
+        # If these methods are declared with attr_reader Ruby will issue a
+        # warning because they are private.
+        # rubocop:disable Style/TrivialAccessors
+
+        # The number of the currently running example_group.
+        def example_group_number
+          @example_group_number
+        end
+
+        # The number of the currently running example (a global counter).
+        def example_number
+          @example_number
+        end
+        # rubocop:enable Style/TrivialAccessors
+
+        def percent_done
+          result = 100.0
+          if @example_count > 0
+            result = (((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0).to_f
+          end
+          result
+        end
+
+        # Override this method if you wish to output extra HTML for a failed
+        # spec. For example, you could output links to images or other files
+        # produced during the specs.
+        def extra_failure_content(failure)
+          RSpec::Support.require_rspec_core "formatters/snippet_extractor"
+          backtrace = failure.exception.backtrace.map do |line|
+            RSpec.configuration.backtrace_formatter.backtrace_line(line)
+          end
+          backtrace.compact!
+          @snippet_extractor ||= SnippetExtractor.new
+          "    <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(backtrace)}</code></pre>"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/html_printer.rb b/rspec-core/lib/rspec/core/formatters/html_printer.rb
new file mode 100644
index 0000000..32a9f97
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/html_printer.rb
@@ -0,0 +1,419 @@
+require 'erb'
+
+module RSpec
+  module Core
+    module Formatters
+      # @private
+      class HtmlPrinter
+        include ERB::Util # For the #h method.
+        def initialize(output)
+          @output = output
+        end
+
+        def print_html_start
+          @output.puts HTML_HEADER
+          @output.puts REPORT_HEADER
+        end
+
+        def print_example_group_end
+          @output.puts "  </dl>"
+          @output.puts "</div>"
+        end
+
+        def print_example_group_start(group_id, description, number_of_parents)
+          @output.puts "<div id=\"div_group_#{group_id}\" class=\"example_group passed\">"
+          @output.puts "  <dl #{indentation_style(number_of_parents)}>"
+          @output.puts "  <dt id=\"example_group_#{group_id}\" class=\"passed\">#{h(description)}</dt>"
+        end
+
+        def print_example_passed(description, run_time)
+          formatted_run_time = "%.5f" % run_time
+          @output.puts "    <dd class=\"example passed\">" \
+            "<span class=\"passed_spec_name\">#{h(description)}</span>" \
+            "<span class='duration'>#{formatted_run_time}s</span></dd>"
+        end
+
+        # rubocop:disable Style/ParameterLists
+        def print_example_failed(pending_fixed, description, run_time, failure_id,
+                                 exception, extra_content, escape_backtrace=false)
+          # rubocop:enable Style/ParameterLists
+          formatted_run_time = "%.5f" % run_time
+
+          @output.puts "    <dd class=\"example #{pending_fixed ? 'pending_fixed' : 'failed'}\">"
+          @output.puts "      <span class=\"failed_spec_name\">#{h(description)}</span>"
+          @output.puts "      <span class=\"duration\">#{formatted_run_time}s</span>"
+          @output.puts "      <div class=\"failure\" id=\"failure_#{failure_id}\">"
+          if exception
+            @output.puts "        <div class=\"message\"><pre>#{h(exception[:message])}</pre></div>"
+            if escape_backtrace
+              @output.puts "        <div class=\"backtrace\"><pre>#{h exception[:backtrace]}</pre></div>"
+            else
+              @output.puts "        <div class=\"backtrace\"><pre>#{exception[:backtrace]}</pre></div>"
+            end
+          end
+          @output.puts extra_content if extra_content
+          @output.puts "      </div>"
+          @output.puts "    </dd>"
+        end
+
+        def print_example_pending(description, pending_message)
+          @output.puts "    <dd class=\"example not_implemented\">" \
+            "<span class=\"not_implemented_spec_name\">#{h(description)} " \
+            "(PENDING: #{h(pending_message)})</span></dd>"
+        end
+
+        def print_summary(duration, example_count, failure_count, pending_count)
+          totals =  "#{example_count} example#{'s' unless example_count == 1}, "
+          totals << "#{failure_count} failure#{'s' unless failure_count == 1}"
+          totals << ", #{pending_count} pending" if pending_count > 0
+
+          formatted_duration = "%.5f" % duration
+
+          @output.puts "<script type=\"text/javascript\">" \
+            "document.getElementById('duration').innerHTML = \"Finished in " \
+            "<strong>#{formatted_duration} seconds</strong>\";</script>"
+          @output.puts "<script type=\"text/javascript\">" \
+            "document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
+          @output.puts "</div>"
+          @output.puts "</div>"
+          @output.puts "</body>"
+          @output.puts "</html>"
+        end
+
+        def flush
+          @output.flush
+        end
+
+        def move_progress(percent_done)
+          @output.puts "    <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
+          @output.flush
+        end
+
+        def make_header_red
+          @output.puts "    <script type=\"text/javascript\">makeRed('rspec-header');</script>"
+        end
+
+        def make_header_yellow
+          @output.puts "    <script type=\"text/javascript\">makeYellow('rspec-header');</script>"
+        end
+
+        def make_example_group_header_red(group_id)
+          @output.puts "    <script type=\"text/javascript\">" \
+                       "makeRed('div_group_#{group_id}');</script>"
+          @output.puts "    <script type=\"text/javascript\">" \
+                       "makeRed('example_group_#{group_id}');</script>"
+        end
+
+        def make_example_group_header_yellow(group_id)
+          @output.puts "    <script type=\"text/javascript\">" \
+                       "makeYellow('div_group_#{group_id}');</script>"
+          @output.puts "    <script type=\"text/javascript\">" \
+                       "makeYellow('example_group_#{group_id}');</script>"
+        end
+
+      private
+
+        def indentation_style(number_of_parents)
+          "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\""
+        end
+
+        # rubocop:disable LineLength
+        REPORT_HEADER = <<-EOF
+<div class="rspec-report">
+
+<div id="rspec-header">
+  <div id="label">
+    <h1>RSpec Code Examples</h1>
+  </div>
+
+  <div id="display-filters">
+    <input id="passed_checkbox"  name="passed_checkbox"  type="checkbox" checked="checked" onchange="apply_filters()" value="1" /> <label for="passed_checkbox">Passed</label>
+    <input id="failed_checkbox"  name="failed_checkbox"  type="checkbox" checked="checked" onchange="apply_filters()" value="2" /> <label for="failed_checkbox">Failed</label>
+    <input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="3" /> <label for="pending_checkbox">Pending</label>
+  </div>
+
+  <div id="summary">
+    <p id="totals"> </p>
+    <p id="duration"> </p>
+  </div>
+</div>
+
+
+<div class="results">
+EOF
+        # rubocop:enable LineLength
+
+        # rubocop:disable LineLength
+        GLOBAL_SCRIPTS = <<-EOF
+
+function addClass(element_id, classname) {
+  document.getElementById(element_id).className += (" " + classname);
+}
+
+function removeClass(element_id, classname) {
+  var elem = document.getElementById(element_id);
+  var classlist = elem.className.replace(classname,'');
+  elem.className = classlist;
+}
+
+function moveProgressBar(percentDone) {
+  document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+
+function makeRed(element_id) {
+  removeClass(element_id, 'passed');
+  removeClass(element_id, 'not_implemented');
+  addClass(element_id,'failed');
+}
+
+function makeYellow(element_id) {
+  var elem = document.getElementById(element_id);
+  if (elem.className.indexOf("failed") == -1) {  // class doesn't includes failed
+    if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
+      removeClass(element_id, 'passed');
+      addClass(element_id,'not_implemented');
+    }
+  }
+}
+
+function apply_filters() {
+  var passed_filter = document.getElementById('passed_checkbox').checked;
+  var failed_filter = document.getElementById('failed_checkbox').checked;
+  var pending_filter = document.getElementById('pending_checkbox').checked;
+
+  assign_display_style("example passed", passed_filter);
+  assign_display_style("example failed", failed_filter);
+  assign_display_style("example not_implemented", pending_filter);
+
+  assign_display_style_for_group("example_group passed", passed_filter);
+  assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter);
+  assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
+}
+
+function get_display_style(display_flag) {
+  var style_mode = 'none';
+  if (display_flag == true) {
+    style_mode = 'block';
+  }
+  return style_mode;
+}
+
+function assign_display_style(classname, display_flag) {
+  var style_mode = get_display_style(display_flag);
+  var elems = document.getElementsByClassName(classname)
+  for (var i=0; i<elems.length;i++) {
+    elems[i].style.display = style_mode;
+  }
+}
+
+function assign_display_style_for_group(classname, display_flag, subgroup_flag) {
+  var display_style_mode = get_display_style(display_flag);
+  var subgroup_style_mode = get_display_style(subgroup_flag);
+  var elems = document.getElementsByClassName(classname)
+  for (var i=0; i<elems.length;i++) {
+    var style_mode = display_style_mode;
+    if ((display_flag != subgroup_flag) && (elems[i].getElementsByTagName('dt')[0].innerHTML.indexOf(", ") != -1)) {
+      elems[i].style.display = subgroup_style_mode;
+    } else {
+      elems[i].style.display = display_style_mode;
+    }
+  }
+}
+EOF
+        # rubocop:enable LineLength
+
+        GLOBAL_STYLES = <<-EOF
+#rspec-header {
+  background: #65C400; color: #fff; height: 4em;
+}
+
+.rspec-report h1 {
+  margin: 0px 10px 0px 10px;
+  padding: 10px;
+  font-family: "Lucida Grande", Helvetica, sans-serif;
+  font-size: 1.8em;
+  position: absolute;
+}
+
+#label {
+  float:left;
+}
+
+#display-filters {
+  float:left;
+  padding: 28px 0 0 40%;
+  font-family: "Lucida Grande", Helvetica, sans-serif;
+}
+
+#summary {
+  float:right;
+  padding: 5px 10px;
+  font-family: "Lucida Grande", Helvetica, sans-serif;
+  text-align: right;
+}
+
+#summary p {
+  margin: 0 0 0 2px;
+}
+
+#summary #totals {
+  font-size: 1.2em;
+}
+
+.example_group {
+  margin: 0 10px 5px;
+  background: #fff;
+}
+
+dl {
+  margin: 0; padding: 0 0 5px;
+  font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+  padding: 3px;
+  background: #65C400;
+  color: #fff;
+  font-weight: bold;
+}
+
+dd {
+  margin: 5px 0 5px 5px;
+  padding: 3px 3px 3px 18px;
+}
+
+dd .duration {
+  padding-left: 5px;
+  text-align: right;
+  right: 0px;
+  float:right;
+}
+
+dd.example.passed {
+  border-left: 5px solid #65C400;
+  border-bottom: 1px solid #65C400;
+  background: #DBFFB4; color: #3D7700;
+}
+
+dd.example.not_implemented {
+  border-left: 5px solid #FAF834;
+  border-bottom: 1px solid #FAF834;
+  background: #FCFB98; color: #131313;
+}
+
+dd.example.pending_fixed {
+  border-left: 5px solid #0000C2;
+  border-bottom: 1px solid #0000C2;
+  color: #0000C2; background: #D3FBFF;
+}
+
+dd.example.failed {
+  border-left: 5px solid #C20000;
+  border-bottom: 1px solid #C20000;
+  color: #C20000; background: #FFFBD3;
+}
+
+
+dt.not_implemented {
+  color: #000000; background: #FAF834;
+}
+
+dt.pending_fixed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+dt.failed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+
+#rspec-header.not_implemented {
+  color: #000000; background: #FAF834;
+}
+
+#rspec-header.pending_fixed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+#rspec-header.failed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+
+.backtrace {
+  color: #000;
+  font-size: 12px;
+}
+
+a {
+  color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+  font-size: 12px;
+  font-family: monospace;
+  color: white;
+  background-color: black;
+  padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+  width: 75px;
+  padding: 0.1em 1em 0.2em 0;
+  color: #000000;
+  background-color: #FFFBD3;
+}
+EOF
+
+        HTML_HEADER = <<-EOF
+<!DOCTYPE html>
+<html lang='en'>
+<head>
+  <title>RSpec results</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <meta http-equiv="Expires" content="-1" />
+  <meta http-equiv="Pragma" content="no-cache" />
+  <style type="text/css">
+  body {
+    margin: 0;
+    padding: 0;
+    background: #fff;
+    font-size: 80%;
+  }
+  </style>
+  <script type="text/javascript">
+    // <![CDATA[
+#{GLOBAL_SCRIPTS}
+    // ]]>
+  </script>
+  <style type="text/css">
+#{GLOBAL_STYLES}
+  </style>
+</head>
+<body>
+EOF
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/json_formatter.rb b/rspec-core/lib/rspec/core/formatters/json_formatter.rb
new file mode 100644
index 0000000..080c105
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/json_formatter.rb
@@ -0,0 +1,94 @@
+RSpec::Support.require_rspec_core "formatters/base_formatter"
+require 'json'
+
+module RSpec
+  module Core
+    module Formatters
+      # @private
+      class JsonFormatter < BaseFormatter
+        Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :close
+
+        attr_reader :output_hash
+
+        def initialize(output)
+          super
+          @output_hash = {}
+        end
+
+        def message(notification)
+          (@output_hash[:messages] ||= []) << notification.message
+        end
+
+        def dump_summary(summary)
+          @output_hash[:summary] = {
+            :duration => summary.duration,
+            :example_count => summary.example_count,
+            :failure_count => summary.failure_count,
+            :pending_count => summary.pending_count
+          }
+          @output_hash[:summary_line] = summary.totals_line
+        end
+
+        def stop(notification)
+          @output_hash[:examples] = notification.examples.map do |example|
+            format_example(example).tap do |hash|
+              e = example.exception
+              if e
+                hash[:exception] =  {
+                  :class => e.class.name,
+                  :message => e.message,
+                  :backtrace => e.backtrace,
+                }
+              end
+            end
+          end
+        end
+
+        def close(_notification)
+          output.write @output_hash.to_json
+          output.close if IO === output && output != $stdout
+        end
+
+        def dump_profile(profile)
+          @output_hash[:profile] = {}
+          dump_profile_slowest_examples(profile)
+          dump_profile_slowest_example_groups(profile)
+        end
+
+        # @api private
+        def dump_profile_slowest_examples(profile)
+          @output_hash[:profile] = {}
+          sorted_examples = profile.slowest_examples
+          @output_hash[:profile][:examples] = sorted_examples.map do |example|
+            format_example(example).tap do |hash|
+              hash[:run_time] = example.execution_result.run_time
+            end
+          end
+          @output_hash[:profile][:slowest] = profile.slow_duration
+          @output_hash[:profile][:total] = profile.duration
+        end
+
+        # @api private
+        def dump_profile_slowest_example_groups(profile)
+          @output_hash[:profile] ||= {}
+          @output_hash[:profile][:groups] = profile.slowest_groups.map do |loc, hash|
+            hash.update(:location => loc)
+          end
+        end
+
+      private
+
+        def format_example(example)
+          {
+            :description => example.description,
+            :full_description => example.full_description,
+            :status => example.execution_result.status.to_s,
+            :file_path => example.metadata[:file_path],
+            :line_number  => example.metadata[:line_number],
+            :run_time => example.execution_result.run_time
+          }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/profile_formatter.rb b/rspec-core/lib/rspec/core/formatters/profile_formatter.rb
new file mode 100644
index 0000000..4b95d93
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/profile_formatter.rb
@@ -0,0 +1,68 @@
+RSpec::Support.require_rspec_core "formatters/console_codes"
+
+module RSpec
+  module Core
+    module Formatters
+      # @api private
+      # Formatter for providing profile output.
+      class ProfileFormatter
+        Formatters.register self, :dump_profile
+
+        def initialize(output)
+          @output = output
+        end
+
+        # @private
+        attr_reader :output
+
+        # @api public
+        #
+        # This method is invoked after the dumping the summary if profiling is
+        # enabled.
+        #
+        # @param profile [ProfileNotification] containing duration,
+        #   slowest_examples and slowest_example_groups
+        def dump_profile(profile)
+          dump_profile_slowest_examples(profile)
+          dump_profile_slowest_example_groups(profile)
+        end
+
+      private
+
+        def dump_profile_slowest_examples(profile)
+          @output.puts "\nTop #{profile.slowest_examples.size} slowest " \
+            "examples (#{Helpers.format_seconds(profile.slow_duration)} " \
+            "seconds, #{profile.percentage}% of total time):\n"
+
+          profile.slowest_examples.each do |example|
+            @output.puts "  #{example.full_description}"
+            @output.puts "    #{bold(Helpers.format_seconds(example.execution_result.run_time))} " \
+                         "#{bold("seconds")} #{format_caller(example.location)}"
+          end
+        end
+
+        def dump_profile_slowest_example_groups(profile)
+          return if profile.slowest_groups.empty?
+
+          @output.puts "\nTop #{profile.slowest_groups.size} slowest example groups:"
+          profile.slowest_groups.each do |loc, hash|
+            average = "#{bold(Helpers.format_seconds(hash[:average]))} #{bold("seconds")} average"
+            total   = "#{Helpers.format_seconds(hash[:total_time])} seconds"
+            count   = Helpers.pluralize(hash[:count], "example")
+            @output.puts "  #{hash[:description]}"
+            @output.puts "    #{average} (#{total} / #{count}) #{loc}"
+          end
+        end
+
+        def format_caller(caller_info)
+          RSpec.configuration.backtrace_formatter.backtrace_line(
+            caller_info.to_s.split(':in `block').first)
+        end
+
+        def bold(text)
+          ConsoleCodes.wrap(text, :bold)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/progress_formatter.rb b/rspec-core/lib/rspec/core/formatters/progress_formatter.rb
new file mode 100644
index 0000000..f0978bc
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/progress_formatter.rb
@@ -0,0 +1,28 @@
+RSpec::Support.require_rspec_core "formatters/base_text_formatter"
+
+module RSpec
+  module Core
+    module Formatters
+      # @private
+      class ProgressFormatter < BaseTextFormatter
+        Formatters.register self, :example_passed, :example_pending, :example_failed, :start_dump
+
+        def example_passed(_notification)
+          output.print ConsoleCodes.wrap('.', :success)
+        end
+
+        def example_pending(_notification)
+          output.print ConsoleCodes.wrap('*', :pending)
+        end
+
+        def example_failed(_notification)
+          output.print ConsoleCodes.wrap('F', :failure)
+        end
+
+        def start_dump(_notification)
+          output.puts
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/protocol.rb b/rspec-core/lib/rspec/core/formatters/protocol.rb
new file mode 100644
index 0000000..f9e2ae5
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/protocol.rb
@@ -0,0 +1,172 @@
+module RSpec
+  module Core
+    module Formatters
+      # This class isn't loaded at runtime but serves to document all of the
+      # notifications implemented as part of the standard interface. The
+      # reporter will issue these during a normal test suite run, but a
+      # formatter will only receive those notifications it has registered
+      # itself to receive. To register a formatter call:
+      #
+      # `::RSpec::Core::Formatters.register class, :list, :of, :notifications`
+      #
+      # e.g.
+      #
+      # `::RSpec::Core::Formatters.register self, :start, :example_started`
+      #
+      # @see RSpec::Core::Formatters::BaseFormatter
+      # @see RSpec::Core::Formatters::BaseTextFormatter
+      # @see RSpec::Core::Reporter
+      class Protocol
+        # @method initialize
+        # @api public
+        #
+        # @param output [IO] the formatter output
+
+        # @method start
+        # @api public
+        # @group Suite Notifications
+        #
+        # This method is invoked before any examples are run, right after
+        # they have all been collected. This can be useful for special
+        # formatters that need to provide progress on feedback (graphical ones).
+        #
+        # This will only be invoked once, and the next one to be invoked
+        # is {#example_group_started}.
+        #
+        # @param notification [StartNotification]
+
+        # @method example_group_started
+        # @api public
+        # @group Group Notifications
+        #
+        # This method is invoked at the beginning of the execution of each
+        # example group.
+        #
+        # The next method to be invoked after this is {#example_passed},
+        # {#example_pending}, or {#example_group_finished}.
+        #
+        # @param notification [GroupNotification] containing example_group
+        #   subclass of `RSpec::Core::ExampleGroup`
+
+        # @method example_group_finished
+        # @api public
+        # @group Group Notifications
+        #
+        # Invoked at the end of the execution of each example group.
+        #
+        # @param notification [GroupNotification] containing example_group
+        #   subclass of `RSpec::Core::ExampleGroup`
+
+        # @method example_started
+        # @api public
+        # @group Example Notifications
+        #
+        # Invoked at the beginning of the execution of each example.
+        #
+        # @param notification [ExampleNotification] containing example subclass
+        #   of `RSpec::Core::Example`
+
+        # @method example_passed
+        # @api public
+        # @group Example Notifications
+        #
+        # Invoked when an example passes.
+        #
+        # @param notification [ExampleNotification] containing example subclass
+        #   of `RSpec::Core::Example`
+
+        # @method example_pending
+        # @api public
+        # @group Example Notifications
+        #
+        # Invoked when an example is pending.
+        #
+        # @param notification [ExampleNotification] containing example subclass
+        #   of `RSpec::Core::Example`
+
+        # @method example_failed
+        # @api public
+        # @group Example Notifications
+        #
+        # Invoked when an example fails.
+        #
+        # @param notification [ExampleNotification] containing example subclass
+        #   of `RSpec::Core::Example`
+
+        # @method message
+        # @api public
+        # @group Suite Notifications
+        #
+        # Used by the reporter to send messages to the output stream.
+        #
+        # @param notification [MessageNotification] containing message
+
+        # @method stop
+        # @api public
+        # @group Suite Notifications
+        #
+        # Invoked after all examples have executed, before dumping post-run
+        # reports.
+        #
+        # @param notification [NullNotification]
+
+        # @method start_dump
+        # @api public
+        # @group Suite Notifications
+        #
+        # This method is invoked after all of the examples have executed. The
+        # next method to be invoked after this one is {#dump_failures}
+        # (BaseTextFormatter then calls {#dump_failures} once for each failed
+        # example).
+        #
+        # @param notification [NullNotification]
+
+        # @method dump_failures
+        # @api public
+        # @group Suite Notifications
+        #
+        # Dumps detailed information about each example failure.
+        #
+        # @param notification [NullNotification]
+
+        # @method dump_summary
+        # @api public
+        # @group Suite Notifications
+        #
+        # This method is invoked after the dumping of examples and failures.
+        # Each parameter is assigned to a corresponding attribute.
+        #
+        # @param summary [SummaryNotification] containing duration,
+        #   example_count, failure_count and pending_count
+
+        # @method dump_profile
+        # @api public
+        # @group Suite Notifications
+        #
+        # This method is invoked after the dumping the summary if profiling is
+        # enabled.
+        #
+        # @param profile [ProfileNotification] containing duration,
+        #   slowest_examples and slowest_example_groups
+
+        # @method dump_pending
+        # @api public
+        # @group Suite Notifications
+        #
+        # Outputs a report of pending examples. This gets invoked
+        # after the summary if option is set to do so.
+        #
+        # @param notification [NullNotification]
+
+        # @method close
+        # @api public
+        # @group Suite Notifications
+        #
+        # Invoked at the very end, `close` allows the formatter to clean
+        # up resources, e.g. open streams, etc.
+        #
+        # @param notification [NullNotification]
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/formatters/snippet_extractor.rb b/rspec-core/lib/rspec/core/formatters/snippet_extractor.rb
new file mode 100644
index 0000000..2546aca
--- /dev/null
+++ b/rspec-core/lib/rspec/core/formatters/snippet_extractor.rb
@@ -0,0 +1,111 @@
+module RSpec
+  module Core
+    module Formatters
+      # @api private
+      #
+      # Extracts code snippets by looking at the backtrace of the passed error
+      # and applies synax highlighting and line numbers using html.
+      class SnippetExtractor
+        # @private
+        class NullConverter
+          def convert(code)
+            %Q(#{code}\n<span class="comment"># Install the coderay gem to get syntax highlighting</span>)
+          end
+        end
+
+        # @private
+        class CoderayConverter
+          def convert(code)
+            CodeRay.scan(code, :ruby).html(:line_numbers => false)
+          end
+        end
+
+        begin
+          require 'coderay'
+          # rubocop:disable Style/ClassVars
+          @@converter = CoderayConverter.new
+        rescue LoadError
+          @@converter = NullConverter.new
+        end
+        # rubocop:enable Style/ClassVars
+
+        # @api private
+        #
+        # Extract lines of code corresponding to  a backtrace.
+        #
+        # @param backtrace [String] the backtrace from a test failure
+        # @return [String] highlighted code snippet indicating where the test
+        #   failure occured
+        #
+        # @see #post_process
+        def snippet(backtrace)
+          raw_code, line = snippet_for(backtrace[0])
+          highlighted = @@converter.convert(raw_code)
+          post_process(highlighted, line)
+        end
+
+        # @api private
+        #
+        # Create a snippet from a line of code.
+        #
+        # @param error_line [String] file name with line number (i.e.
+        #   'foo_spec.rb:12')
+        # @return [String] lines around the target line within the file
+        #
+        # @see #lines_around
+        def snippet_for(error_line)
+          if error_line =~ /(.*):(\d+)/
+            file = Regexp.last_match[1]
+            line = Regexp.last_match[2].to_i
+            [lines_around(file, line), line]
+          else
+            ["# Couldn't get snippet for #{error_line}", 1]
+          end
+        end
+
+        # @api private
+        #
+        # Extract lines of code centered around a particular line within a
+        # source file.
+        #
+        # @param file [String] filename
+        # @param line [Fixnum] line number
+        # @return [String] lines around the target line within the file (2 above
+        #   and 1 below).
+        def lines_around(file, line)
+          if File.file?(file)
+            lines = File.read(file).split("\n")
+            min = [0, line - 3].max
+            max = [line + 1, lines.length - 1].min
+            selected_lines = []
+            selected_lines.join("\n")
+            lines[min..max].join("\n")
+          else
+            "# Couldn't get snippet for #{file}"
+          end
+        rescue SecurityError
+          "# Couldn't get snippet for #{file}"
+        end
+
+        # @api private
+        #
+        # Adds line numbers to all lines and highlights the line where the
+        # failure occurred using html `span` tags.
+        #
+        # @param highlighted [String] syntax-highlighted snippet surrounding the
+        #   offending line of code
+        # @param offending_line [Fixnum] line where failure occured
+        # @return [String] completed snippet
+        def post_process(highlighted, offending_line)
+          new_lines = []
+          highlighted.split("\n").each_with_index do |line, i|
+            new_line = "<span class=\"linenum\">#{offending_line + i - 2}</span>#{line}"
+            new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
+            new_lines << new_line
+          end
+          new_lines.join("\n")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/hooks.rb b/rspec-core/lib/rspec/core/hooks.rb
new file mode 100644
index 0000000..9c56017
--- /dev/null
+++ b/rspec-core/lib/rspec/core/hooks.rb
@@ -0,0 +1,632 @@
+module RSpec
+  module Core
+    # Provides `before`, `after` and `around` hooks as a means of
+    # supporting common setup and teardown. This module is extended
+    # onto {ExampleGroup}, making the methods available from any `describe`
+    # or `context` block and included in {Configuration}, making them
+    # available off of the configuration object to define global setup
+    # or teardown logic.
+    module Hooks
+      # @api public
+      #
+      # @overload before(&block)
+      # @overload before(scope, &block)
+      #   @param scope [Symbol] `:example`, `:context`, or `:suite`
+      #     (defaults to `:example`)
+      # @overload before(scope, conditions, &block)
+      #   @param scope [Symbol] `:example`, `:context`, or `:suite`
+      #     (defaults to `:example`)
+      #   @param conditions [Hash]
+      #     constrains this hook to examples matching these conditions e.g.
+      #     `before(:example, :ui => true) { ... }` will only run with examples
+      #     or groups declared with `:ui => true`.
+      # @overload before(conditions, &block)
+      #   @param conditions [Hash]
+      #     constrains this hook to examples matching these conditions e.g.
+      #     `before(:example, :ui => true) { ... }` will only run with examples
+      #     or groups declared with `:ui => true`.
+      #
+      # @see #after
+      # @see #around
+      # @see ExampleGroup
+      # @see SharedContext
+      # @see SharedExampleGroup
+      # @see Configuration
+      #
+      # Declare a block of code to be run before each example (using `:example`)
+      # or once before any example (using `:context`). These are usually
+      # declared directly in the {ExampleGroup} to which they apply, but they
+      # can also be shared across multiple groups.
+      #
+      # You can also use `before(:suite)` to run a block of code before any
+      # example groups are run. This should be declared in {RSpec.configure}.
+      #
+      # Instance variables declared in `before(:example)` or `before(:context)`
+      # are accessible within each example.
+      #
+      # ### Order
+      #
+      # `before` hooks are stored in three scopes, which are run in order:
+      # `:suite`, `:context`, and `:example`. They can also be declared in
+      # several different places: `RSpec.configure`, a parent group, the current
+      # group. They are run in the following order:
+      #
+      #     before(:suite)    # Declared in RSpec.configure.
+      #     before(:context)  # Declared in RSpec.configure.
+      #     before(:context)  # Declared in a parent group.
+      #     before(:context)  # Declared in the current group.
+      #     before(:example)  # Declared in RSpec.configure.
+      #     before(:example)  # Declared in a parent group.
+      #     before(:example)  # Declared in the current group.
+      #
+      # If more than one `before` is declared within any one scope, they are run
+      # in the order in which they are declared.
+      #
+      # ### Conditions
+      #
+      # When you add a conditions hash to `before(:example)` or
+      # `before(:context)`, RSpec will only apply that hook to groups or
+      # examples that match the conditions. e.g.
+      #
+      #     RSpec.configure do |config|
+      #       config.before(:example, :authorized => true) do
+      #         log_in_as :authorized_user
+      #       end
+      #     end
+      #
+      #     describe Something, :authorized => true do
+      #       # The before hook will run in before each example in this group.
+      #     end
+      #
+      #     describe SomethingElse do
+      #       it "does something", :authorized => true do
+      #         # The before hook will run before this example.
+      #       end
+      #
+      #       it "does something else" do
+      #         # The hook will not run before this example.
+      #       end
+      #     end
+      #
+      # Note that filtered config `:context` hooks can still be applied
+      # to individual examples that have matching metadata. Just like
+      # Ruby's object model is that every object has a singleton class
+      # which has only a single instance, RSpec's model is that every
+      # example has a singleton example group containing just the one
+      # example.
+      #
+      # ### Warning: `before(:suite, :with => :conditions)`
+      #
+      # The conditions hash is used to match against specific examples. Since
+      # `before(:suite)` is not run in relation to any specific example or
+      # group, conditions passed along with `:suite` are effectively ignored.
+      #
+      # ### Exceptions
+      #
+      # When an exception is raised in a `before` block, RSpec skips any
+      # subsequent `before` blocks and the example, but runs all of the
+      # `after(:example)` and `after(:context)` hooks.
+      #
+      # ### Warning: implicit before blocks
+      #
+      # `before` hooks can also be declared in shared contexts which get
+      # included implicitly either by you or by extension libraries. Since
+      # RSpec runs these in the order in which they are declared within each
+      # scope, load order matters, and can lead to confusing results when one
+      # before block depends on state that is prepared in another before block
+      # that gets run later.
+      #
+      # ### Warning: `before(:context)`
+      #
+      # It is very tempting to use `before(:context)` to speed things up, but we
+      # recommend that you avoid this as there are a number of gotchas, as well
+      # as things that simply don't work.
+      #
+      # #### Context
+      #
+      # `before(:context)` is run in an example that is generated to provide
+      # group context for the block.
+      #
+      # #### Instance variables
+      #
+      # Instance variables declared in `before(:context)` are shared across all
+      # the examples in the group. This means that each example can change the
+      # state of a shared object, resulting in an ordering dependency that can
+      # make it difficult to reason about failures.
+      #
+      # #### Unsupported RSpec constructs
+      #
+      # RSpec has several constructs that reset state between each example
+      # automatically. These are not intended for use from within
+      # `before(:context)`:
+      #
+      #   * `let` declarations
+      #   * `subject` declarations
+      #   * Any mocking, stubbing or test double declaration
+      #
+      # ### other frameworks
+      #
+      # Mock object frameworks and database transaction managers (like
+      # ActiveRecord) are typically designed around the idea of setting up
+      # before an example, running that one example, and then tearing down. This
+      # means that mocks and stubs can (sometimes) be declared in
+      # `before(:context)`, but get torn down before the first real example is
+      # ever run.
+      #
+      # You _can_ create database-backed model objects in a `before(:context)`
+      # in rspec-rails, but it will not be wrapped in a transaction for you, so
+      # you are on your own to clean up in an `after(:context)` block.
+      #
+      # @example before(:example) declared in an {ExampleGroup}
+      #
+      #     describe Thing do
+      #       before(:example) do
+      #         @thing = Thing.new
+      #       end
+      #
+      #       it "does something" do
+      #         # Here you can access @thing.
+      #       end
+      #     end
+      #
+      # @example before(:context) declared in an {ExampleGroup}
+      #
+      #     describe Parser do
+      #       before(:context) do
+      #         File.open(file_to_parse, 'w') do |f|
+      #           f.write <<-CONTENT
+      #             stuff in the file
+      #           CONTENT
+      #         end
+      #       end
+      #
+      #       it "parses the file" do
+      #         Parser.parse(file_to_parse)
+      #       end
+      #
+      #       after(:context) do
+      #         File.delete(file_to_parse)
+      #       end
+      #     end
+      #
+      # @note The `:example` and `:context` scopes are also available as
+      #       `:each` and `:all`, respectively. Use whichever you prefer.
+      # @note The `:scope` alias is only supported for hooks registered on
+      #       `RSpec.configuration` since they exist independently of any
+      #       example or example group.
+      def before(*args, &block)
+        hooks.register :append, :before, *args, &block
+      end
+
+      alias_method :append_before, :before
+
+      # Adds `block` to the front of the list of `before` blocks in the same
+      # scope (`:example`, `:context`, or `:suite`).
+      #
+      # See {#before} for scoping semantics.
+      def prepend_before(*args, &block)
+        hooks.register :prepend, :before, *args, &block
+      end
+
+      # @api public
+      # @overload after(&block)
+      # @overload after(scope, &block)
+      #   @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to
+      #     `:example`)
+      # @overload after(scope, conditions, &block)
+      #   @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to
+      #     `:example`)
+      #   @param conditions [Hash]
+      #     constrains this hook to examples matching these conditions e.g.
+      #     `after(:example, :ui => true) { ... }` will only run with examples
+      #     or groups declared with `:ui => true`.
+      # @overload after(conditions, &block)
+      #   @param conditions [Hash]
+      #     constrains this hook to examples matching these conditions e.g.
+      #     `after(:example, :ui => true) { ... }` will only run with examples
+      #     or groups declared with `:ui => true`.
+      #
+      # @see #before
+      # @see #around
+      # @see ExampleGroup
+      # @see SharedContext
+      # @see SharedExampleGroup
+      # @see Configuration
+      #
+      # Declare a block of code to be run after each example (using `:example`)
+      # or once after all examples n the context (using `:context`). See
+      # {#before} for more information about ordering.
+      #
+      # ### Exceptions
+      #
+      # `after` hooks are guaranteed to run even when there are exceptions in
+      # `before` hooks or examples. When an exception is raised in an after
+      # block, the exception is captured for later reporting, and subsequent
+      # `after` blocks are run.
+      #
+      # ### Order
+      #
+      # `after` hooks are stored in three scopes, which are run in order:
+      # `:example`, `:context`, and `:suite`. They can also be declared in
+      # several different places: `RSpec.configure`, a parent group, the current
+      # group. They are run in the following order:
+      #
+      #     after(:example) # Declared in the current group.
+      #     after(:example) # Declared in a parent group.
+      #     after(:example) # Declared in RSpec.configure.
+      #     after(:context) # Declared in the current group.
+      #     after(:context) # Declared in a parent group.
+      #     after(:context) # Declared in RSpec.configure.
+      #     after(:suite)   # Declared in RSpec.configure.
+      #
+      # This is the reverse of the order in which `before` hooks are run.
+      # Similarly, if more than one `after` is declared within any one scope,
+      # they are run in reverse order of that in which they are declared.
+      #
+      # @note The `:example` and `:context` scopes are also available as
+      #       `:each` and `:all`, respectively. Use whichever you prefer.
+      # @note The `:scope` alias is only supported for hooks registered on
+      #       `RSpec.configuration` since they exist independently of any
+      #       example or example group.
+      def after(*args, &block)
+        hooks.register :prepend, :after, *args, &block
+      end
+
+      alias_method :prepend_after, :after
+
+      # Adds `block` to the back of the list of `after` blocks in the same
+      # scope (`:example`, `:context`, or `:suite`).
+      #
+      # See {#after} for scoping semantics.
+      def append_after(*args, &block)
+        hooks.register :append, :after, *args, &block
+      end
+
+      # @api public
+      # @overload around(&block)
+      # @overload around(scope, &block)
+      #   @param scope [Symbol] `:example` (defaults to `:example`)
+      #     present for syntax parity with `before` and `after`, but
+      #     `:example`/`:each` is the only supported value.
+      # @overload around(scope, conditions, &block)
+      #   @param scope [Symbol] `:example` (defaults to `:example`)
+      #     present for syntax parity with `before` and `after`, but
+      #     `:example`/`:each` is the only supported value.
+      #   @param conditions [Hash] constrains this hook to examples matching
+      #     these conditions e.g. `around(:example, :ui => true) { ... }` will
+      #     only run with examples or groups declared with `:ui => true`.
+      # @overload around(conditions, &block)
+      #   @param conditions [Hash] constrains this hook to examples matching
+      #     these conditions e.g. `around(:example, :ui => true) { ... }` will
+      #     only run with examples or groups declared with `:ui => true`.
+      #
+      # @yield [Example] the example to run
+      #
+      # @note the syntax of `around` is similar to that of `before` and `after`
+      #   but the semantics are quite different. `before` and `after` hooks are
+      #   run in the context of of the examples with which they are associated,
+      #   whereas `around` hooks are actually responsible for running the
+      #   examples. Consequently, `around` hooks do not have direct access to
+      #   resources that are made available within the examples and their
+      #   associated `before` and `after` hooks.
+      #
+      # @note `:example`/`:each` is the only supported scope.
+      #
+      # Declare a block of code, parts of which will be run before and parts
+      # after the example. It is your responsibility to run the example:
+      #
+      #     around(:example) do |ex|
+      #       # Do some stuff before.
+      #       ex.run
+      #       # Do some stuff after.
+      #     end
+      #
+      # The yielded example aliases `run` with `call`, which lets you treat it
+      # like a `Proc`. This is especially handy when working with libaries
+      # that manage their own setup and teardown using a block or proc syntax,
+      # e.g.
+      #
+      #     around(:example) {|ex| Database.transaction(&ex)}
+      #     around(:example) {|ex| FakeFS(&ex)}
+      #
+      def around(*args, &block)
+        hooks.register :prepend, :around, *args, &block
+      end
+
+      # @private
+      # Holds the various registered hooks.
+      def hooks
+        @hooks ||= HookCollections.new(self, FilterableItemRepository::UpdateOptimized)
+      end
+
+    private
+
+      # @private
+      class Hook
+        attr_reader :block, :options
+
+        def initialize(block, options)
+          @block = block
+          @options = options
+        end
+      end
+
+      # @private
+      class BeforeHook < Hook
+        def run(example)
+          example.instance_exec(example, &block)
+        end
+      end
+
+      # @private
+      class AfterHook < Hook
+        def run(example)
+          example.instance_exec_with_rescue("in an after hook", &block)
+        end
+      end
+
+      # @private
+      class AfterContextHook < Hook
+        def run(example)
+          example.instance_exec(example, &block)
+        rescue Exception => e
+          # TODO: Come up with a better solution for this.
+          RSpec.configuration.reporter.message <<-EOS
+
+An error occurred in an `after(:context)` hook.
+  #{e.class}: #{e.message}
+  occurred at #{e.backtrace.first}
+
+EOS
+        end
+      end
+
+      # @private
+      class AroundHook < Hook
+        def execute_with(example, procsy)
+          example.instance_exec(procsy, &block)
+          return if procsy.executed?
+          Pending.mark_skipped!(example,
+                                "#{hook_description} did not execute the example")
+        end
+
+        if Proc.method_defined?(:source_location)
+          def hook_description
+            "around hook at #{Metadata.relative_path(block.source_location.join(':'))}"
+          end
+        else
+          def hook_description
+            "around hook"
+          end
+        end
+      end
+
+      # @private
+      #
+      # This provides the primary API used by other parts of rspec-core. By hiding all
+      # implementation details behind this facade, it's allowed us to heavily optimize
+      # this, so that, for example, hook collection objects are only instantiated when
+      # a hook is added. This allows us to avoid many object allocations for the common
+      # case of a group having no hooks.
+      #
+      # This is only possible because this interface provides a "tell, don't ask"-style
+      # API, so that callers _tell_ this class what to do with the hooks, rather than
+      # asking this class for a list of hooks, and then doing something with them.
+      class HookCollections
+        def initialize(owner, filterable_item_repo_class)
+          @owner                      = owner
+          @filterable_item_repo_class = filterable_item_repo_class
+          @before_example_hooks       = nil
+          @after_example_hooks        = nil
+          @before_context_hooks       = nil
+          @after_context_hooks        = nil
+          @around_example_hooks       = nil
+        end
+
+        def register_globals(host, globals)
+          parent_groups = host.parent_groups
+
+          process(host, parent_groups, globals, :before, :example, &:options)
+          process(host, parent_groups, globals, :after,  :example, &:options)
+          process(host, parent_groups, globals, :around, :example, &:options)
+
+          process(host, parent_groups, globals, :before, :context, &:options)
+          process(host, parent_groups, globals, :after,  :context, &:options)
+        end
+
+        def register_global_singleton_context_hooks(example, globals)
+          parent_groups = example.example_group.parent_groups
+
+          process(example, parent_groups, globals, :before, :context) { {} }
+          process(example, parent_groups, globals, :after,  :context) { {} }
+        end
+
+        def register(prepend_or_append, position, *args, &block)
+          scope, options = scope_and_options_from(*args)
+
+          if scope == :suite
+            # TODO: consider making this an error in RSpec 4. For SemVer reasons,
+            # we are only warning in RSpec 3.
+            RSpec.warn_with "WARNING: `#{position}(:suite)` hooks are only supported on " \
+                            "the RSpec configuration object. This " \
+                            "`#{position}(:suite)` hook, registered on an example " \
+                            "group, will be ignored."
+            return
+          end
+
+          hook = HOOK_TYPES[position][scope].new(block, options)
+          ensure_hooks_initialized_for(position, scope).__send__(prepend_or_append, hook, options)
+        end
+
+        # @private
+        #
+        # Runs all of the blocks stored with the hook in the context of the
+        # example. If no example is provided, just calls the hook directly.
+        def run(position, scope, example_or_group)
+          return if RSpec.configuration.dry_run?
+
+          if scope == :context
+            run_owned_hooks_for(position, :context, example_or_group)
+          else
+            case position
+            when :before then run_example_hooks_for(example_or_group, :before, :reverse_each)
+            when :after  then run_example_hooks_for(example_or_group, :after,  :each)
+            when :around then run_around_example_hooks_for(example_or_group) { yield }
+            end
+          end
+        end
+
+        SCOPES = [:example, :context]
+
+        SCOPE_ALIASES = { :each => :example, :all => :context }
+
+        HOOK_TYPES = {
+          :before => Hash.new { BeforeHook },
+          :after  => Hash.new { AfterHook  },
+          :around => Hash.new { AroundHook }
+        }
+
+        HOOK_TYPES[:after][:context] = AfterContextHook
+
+      protected
+
+        EMPTY_HOOK_ARRAY = [].freeze
+
+        def matching_hooks_for(position, scope, example_or_group)
+          repository = hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }
+
+          # It would be nice to not have to switch on type here, but
+          # we don't want to define `ExampleGroup#metadata` because then
+          # `metadata` from within an individual example would return the
+          # group's metadata but the user would probably expect it to be
+          # the example's metadata.
+          metadata = case example_or_group
+                     when ExampleGroup then example_or_group.class.metadata
+                     else example_or_group.metadata
+                     end
+
+          repository.items_for(metadata)
+        end
+
+        def all_hooks_for(position, scope)
+          hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }.items_and_filters.map(&:first)
+        end
+
+        def run_owned_hooks_for(position, scope, example_or_group)
+          matching_hooks_for(position, scope, example_or_group).each do |hook|
+            hook.run(example_or_group)
+          end
+        end
+
+        def processable_hooks_for(position, scope, host)
+          if scope == :example
+            all_hooks_for(position, scope)
+          else
+            matching_hooks_for(position, scope, host)
+          end
+        end
+
+      private
+
+        def hooks_for(position, scope)
+          if position == :before
+            scope == :example ? @before_example_hooks : @before_context_hooks
+          elsif position == :after
+            scope == :example ? @after_example_hooks : @after_context_hooks
+          else # around
+            @around_example_hooks
+          end || yield
+        end
+
+        def ensure_hooks_initialized_for(position, scope)
+          if position == :before
+            if scope == :example
+              @before_example_hooks ||= @filterable_item_repo_class.new(:all?)
+            else
+              @before_context_hooks ||= @filterable_item_repo_class.new(:all?)
+            end
+          elsif position == :after
+            if scope == :example
+              @after_example_hooks ||= @filterable_item_repo_class.new(:all?)
+            else
+              @after_context_hooks ||= @filterable_item_repo_class.new(:all?)
+            end
+          else # around
+            @around_example_hooks ||= @filterable_item_repo_class.new(:all?)
+          end
+        end
+
+        def process(host, parent_groups, globals, position, scope)
+          hooks_to_process = globals.processable_hooks_for(position, scope, host)
+          return if hooks_to_process.empty?
+
+          hooks_to_process -= FlatMap.flat_map(parent_groups) do |group|
+            group.hooks.all_hooks_for(position, scope)
+          end
+          return if hooks_to_process.empty?
+
+          repository = ensure_hooks_initialized_for(position, scope)
+          hooks_to_process.each { |hook| repository.append hook, (yield hook) }
+        end
+
+        def scope_and_options_from(*args)
+          return :suite if args.first == :suite
+          scope = extract_scope_from(args)
+          meta  = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
+          return scope, meta
+        end
+
+        def extract_scope_from(args)
+          if known_scope?(args.first)
+            normalized_scope_for(args.shift)
+          elsif args.any? { |a| a.is_a?(Symbol) }
+            error_message = "You must explicitly give a scope " \
+              "(#{SCOPES.join(", ")}) or scope alias " \
+              "(#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as " \
+              "metadata for a hook."
+            raise ArgumentError.new error_message
+          else
+            :example
+          end
+        end
+
+        def known_scope?(scope)
+          SCOPES.include?(scope) || SCOPE_ALIASES.keys.include?(scope)
+        end
+
+        def normalized_scope_for(scope)
+          SCOPE_ALIASES[scope] || scope
+        end
+
+        def run_example_hooks_for(example, position, each_method)
+          owner_parent_groups.__send__(each_method) do |group|
+            group.hooks.run_owned_hooks_for(position, :example, example)
+          end
+        end
+
+        def run_around_example_hooks_for(example)
+          hooks = FlatMap.flat_map(owner_parent_groups) do |group|
+            group.hooks.matching_hooks_for(:around, :example, example)
+          end
+
+          return yield if hooks.empty? # exit early to avoid the extra allocation cost of `Example::Procsy`
+
+          initial_procsy = Example::Procsy.new(example) { yield }
+          hooks.inject(initial_procsy) do |procsy, around_hook|
+            procsy.wrap { around_hook.execute_with(example, procsy) }
+          end.call
+        end
+
+        if respond_to?(:singleton_class) && singleton_class.ancestors.include?(singleton_class)
+          def owner_parent_groups
+            @owner.parent_groups
+          end
+        else # Ruby < 2.1 (see https://bugs.ruby-lang.org/issues/8035)
+          def owner_parent_groups
+            @owner_parent_groups ||= [@owner] + @owner.parent_groups
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/memoized_helpers.rb b/rspec-core/lib/rspec/core/memoized_helpers.rb
new file mode 100644
index 0000000..bc95a07
--- /dev/null
+++ b/rspec-core/lib/rspec/core/memoized_helpers.rb
@@ -0,0 +1,472 @@
+module RSpec
+  module Core
+    # This module is included in {ExampleGroup}, making the methods
+    # available to be called from within example blocks.
+    #
+    # @see ClassMethods
+    module MemoizedHelpers
+      # @note `subject` was contributed by Joe Ferris to support the one-liner
+      #   syntax embraced by shoulda matchers:
+      #
+      #       describe Widget do
+      #         it { is_expected.to validate_presence_of(:name) }
+      #         # or
+      #         it { should validate_presence_of(:name) }
+      #       end
+      #
+      #   While the examples below demonstrate how to use `subject`
+      #   explicitly in examples, we recommend that you define a method with
+      #   an intention revealing name instead.
+      #
+      # @example
+      #
+      #   # Explicit declaration of subject.
+      #   describe Person do
+      #     subject { Person.new(:birthdate => 19.years.ago) }
+      #     it "should be eligible to vote" do
+      #       subject.should be_eligible_to_vote
+      #       # ^ ^ explicit reference to subject not recommended
+      #     end
+      #   end
+      #
+      #   # Implicit subject => { Person.new }.
+      #   describe Person do
+      #     it "should be eligible to vote" do
+      #       subject.should be_eligible_to_vote
+      #       # ^ ^ explicit reference to subject not recommended
+      #     end
+      #   end
+      #
+      #   # One-liner syntax - expectation is set on the subject.
+      #   describe Person do
+      #     it { is_expected.to be_eligible_to_vote }
+      #     # or
+      #     it { should be_eligible_to_vote }
+      #   end
+      #
+      # @note Because `subject` is designed to create state that is reset
+      #   between each example, and `before(:context)` is designed to setup
+      #   state that is shared across _all_ examples in an example group,
+      #   `subject` is _not_ intended to be used in a `before(:context)` hook.
+      #
+      # @see #should
+      # @see #should_not
+      # @see #is_expected
+      def subject
+        __memoized.fetch(:subject) do
+          __memoized[:subject] = begin
+            described = described_class || self.class.metadata.fetch(:description_args).first
+            Class === described ? described.new : described
+          end
+        end
+      end
+
+      # When `should` is called with no explicit receiver, the call is
+      # delegated to the object returned by `subject`. Combined with an
+      # implicit subject this supports very concise expressions.
+      #
+      # @example
+      #
+      #   describe Person do
+      #     it { should be_eligible_to_vote }
+      #   end
+      #
+      # @see #subject
+      # @see #is_expected
+      #
+      # @note This only works if you are using rspec-expectations.
+      # @note If you are using RSpec's newer expect-based syntax you may
+      #       want to use `is_expected.to` instead of `should`.
+      def should(matcher=nil, message=nil)
+        RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
+      end
+
+      # Just like `should`, `should_not` delegates to the subject (implicit or
+      # explicit) of the example group.
+      #
+      # @example
+      #
+      #   describe Person do
+      #     it { should_not be_eligible_to_vote }
+      #   end
+      #
+      # @see #subject
+      # @see #is_expected
+      #
+      # @note This only works if you are using rspec-expectations.
+      # @note If you are using RSpec's newer expect-based syntax you may
+      #       want to use `is_expected.to_not` instead of `should_not`.
+      def should_not(matcher=nil, message=nil)
+        RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
+      end
+
+      # Wraps the `subject` in `expect` to make it the target of an expectation.
+      # Designed to read nicely for one-liners.
+      #
+      # @example
+      #
+      #   describe [1, 2, 3] do
+      #     it { is_expected.to be_an Array }
+      #     it { is_expected.not_to include 4 }
+      #   end
+      #
+      # @see #subject
+      # @see #should
+      # @see #should_not
+      #
+      # @note This only works if you are using rspec-expectations.
+      def is_expected
+        expect(subject)
+      end
+
+    private
+
+      # @private
+      def __memoized
+        @__memoized ||= {}
+      end
+
+      # Used internally to customize the behavior of the
+      # memoized hash when used in a `before(:context)` hook.
+      #
+      # @private
+      class ContextHookMemoizedHash
+        def self.isolate_for_context_hook(example_group_instance)
+          hash = self
+
+          example_group_instance.instance_exec do
+            @__memoized = hash
+
+            begin
+              yield
+            ensure
+              @__memoized = nil
+            end
+          end
+        end
+
+        def self.fetch(key, &_block)
+          description = if key == :subject
+                          "subject"
+                        else
+                          "let declaration `#{key}`"
+                        end
+
+          raise <<-EOS
+#{description} accessed in #{article} #{hook_expression} hook at:
+  #{CallerFilter.first_non_rspec_line}
+
+`let` and `subject` declarations are not intended to be called
+in #{article} #{hook_expression} hook, as they exist to define state that
+is reset between each example, while #{hook_expression} exists to
+#{hook_intention}.
+EOS
+        end
+
+        # @private
+        class Before < self
+          def self.hook_expression
+            "`before(:context)`"
+          end
+
+          def self.article
+            "a"
+          end
+
+          def self.hook_intention
+            "define state that is shared across examples in an example group"
+          end
+        end
+
+        # @private
+        class After < self
+          def self.hook_expression
+            "`after(:context)`"
+          end
+
+          def self.article
+            "an"
+          end
+
+          def self.hook_intention
+            "cleanup state that is shared across examples in an example group"
+          end
+        end
+      end
+
+      # This module is extended onto {ExampleGroup}, making the methods
+      # available to be called from within example group blocks.
+      # You can think of them as being analagous to class macros.
+      module ClassMethods
+        # Generates a method whose return value is memoized after the first
+        # call. Useful for reducing duplication between examples that assign
+        # values to the same local variable.
+        #
+        # @note `let` _can_ enhance readability when used sparingly (1,2, or
+        #   maybe 3 declarations) in any given example group, but that can
+        #   quickly degrade with overuse. YMMV.
+        #
+        # @note `let` uses an `||=` conditional that has the potential to
+        #   behave in surprising ways in examples that spawn separate threads,
+        #   though we have yet to see this in practice. You've been warned.
+        #
+        # @note Because `let` is designed to create state that is reset between
+        #   each example, and `before(:context)` is designed to setup state that
+        #   is shared across _all_ examples in an example group, `let` is _not_
+        #   intended to be used in a `before(:context)` hook.
+        #
+        # @example
+        #
+        #   describe Thing do
+        #     let(:thing) { Thing.new }
+        #
+        #     it "does something" do
+        #       # First invocation, executes block, memoizes and returns result.
+        #       thing.do_something
+        #
+        #       # Second invocation, returns the memoized value.
+        #       thing.should be_something
+        #     end
+        #   end
+        def let(name, &block)
+          # We have to pass the block directly to `define_method` to
+          # allow it to use method constructs like `super` and `return`.
+          raise "#let or #subject called without a block" if block.nil?
+          MemoizedHelpers.module_for(self).__send__(:define_method, name, &block)
+
+          # Apply the memoization. The method has been defined in an ancestor
+          # module so we can use `super` here to get the value.
+          if block.arity == 1
+            define_method(name) { __memoized.fetch(name) { |k| __memoized[k] = super(RSpec.current_example, &nil) } }
+          else
+            define_method(name) { __memoized.fetch(name) { |k| __memoized[k] = super(&nil) } }
+          end
+        end
+
+        # Just like `let`, except the block is invoked by an implicit `before`
+        # hook. This serves a dual purpose of setting up state and providing a
+        # memoized reference to that state.
+        #
+        # @example
+        #
+        #   class Thing
+        #     def self.count
+        #       @count ||= 0
+        #     end
+        #
+        #     def self.count=(val)
+        #       @count += val
+        #     end
+        #
+        #     def self.reset_count
+        #       @count = 0
+        #     end
+        #
+        #     def initialize
+        #       self.class.count += 1
+        #     end
+        #   end
+        #
+        #   describe Thing do
+        #     after(:example) { Thing.reset_count }
+        #
+        #     context "using let" do
+        #       let(:thing) { Thing.new }
+        #
+        #       it "is not invoked implicitly" do
+        #         Thing.count.should eq(0)
+        #       end
+        #
+        #       it "can be invoked explicitly" do
+        #         thing
+        #         Thing.count.should eq(1)
+        #       end
+        #     end
+        #
+        #     context "using let!" do
+        #       let!(:thing) { Thing.new }
+        #
+        #       it "is invoked implicitly" do
+        #         Thing.count.should eq(1)
+        #       end
+        #
+        #       it "returns memoized version on first invocation" do
+        #         thing
+        #         Thing.count.should eq(1)
+        #       end
+        #     end
+        #   end
+        def let!(name, &block)
+          let(name, &block)
+          before { __send__(name) }
+        end
+
+        # Declares a `subject` for an example group which can then be wrapped
+        # with `expect` using `is_expected` to make it the target of an
+        # expectation in a concise, one-line example.
+        #
+        # Given a `name`, defines a method with that name which returns the
+        # `subject`. This lets you declare the subject once and access it
+        # implicitly in one-liners and explicitly using an intention revealing
+        # name.
+        #
+        # When given a `name`, calling `super` in the block is not supported.
+        #
+        # @param name [String,Symbol] used to define an accessor with an
+        #   intention revealing name
+        # @param block defines the value to be returned by `subject` in examples
+        #
+        # @example
+        #
+        #   describe CheckingAccount, "with $50" do
+        #     subject { CheckingAccount.new(Money.new(50, :USD)) }
+        #     it { is_expected.to have_a_balance_of(Money.new(50, :USD)) }
+        #     it { is_expected.not_to be_overdrawn }
+        #   end
+        #
+        #   describe CheckingAccount, "with a non-zero starting balance" do
+        #     subject(:account) { CheckingAccount.new(Money.new(50, :USD)) }
+        #     it { is_expected.not_to be_overdrawn }
+        #     it "has a balance equal to the starting balance" do
+        #       account.balance.should eq(Money.new(50, :USD))
+        #     end
+        #   end
+        #
+        # @see MemoizedHelpers#should
+        # @see MemoizedHelpers#should_not
+        # @see MemoizedHelpers#is_expected
+        def subject(name=nil, &block)
+          if name
+            let(name, &block)
+            alias_method :subject, name
+
+            self::NamedSubjectPreventSuper.__send__(:define_method, name) do
+              raise NotImplementedError, "`super` in named subjects is not supported"
+            end
+          else
+            let(:subject, &block)
+          end
+        end
+
+        # Just like `subject`, except the block is invoked by an implicit
+        # `before` hook. This serves a dual purpose of setting up state and
+        # providing a memoized reference to that state.
+        #
+        # @example
+        #
+        #   class Thing
+        #     def self.count
+        #       @count ||= 0
+        #     end
+        #
+        #     def self.count=(val)
+        #       @count += val
+        #     end
+        #
+        #     def self.reset_count
+        #       @count = 0
+        #     end
+        #
+        #     def initialize
+        #       self.class.count += 1
+        #     end
+        #   end
+        #
+        #   describe Thing do
+        #     after(:example) { Thing.reset_count }
+        #
+        #     context "using subject" do
+        #       subject { Thing.new }
+        #
+        #       it "is not invoked implicitly" do
+        #         Thing.count.should eq(0)
+        #       end
+        #
+        #       it "can be invoked explicitly" do
+        #         subject
+        #         Thing.count.should eq(1)
+        #       end
+        #     end
+        #
+        #     context "using subject!" do
+        #       subject!(:thing) { Thing.new }
+        #
+        #       it "is invoked implicitly" do
+        #         Thing.count.should eq(1)
+        #       end
+        #
+        #       it "returns memoized version on first invocation" do
+        #         subject
+        #         Thing.count.should eq(1)
+        #       end
+        #     end
+        #   end
+        def subject!(name=nil, &block)
+          subject(name, &block)
+          before { subject }
+        end
+      end
+
+      # @private
+      #
+      # Gets the LetDefinitions module. The module is mixed into
+      # the example group and is used to hold all let definitions.
+      # This is done so that the block passed to `let` can be
+      # forwarded directly on to `define_method`, so that all method
+      # constructs (including `super` and `return`) can be used in
+      # a `let` block.
+      #
+      # The memoization is provided by a method definition on the
+      # example group that supers to the LetDefinitions definition
+      # in order to get the value to memoize.
+      def self.module_for(example_group)
+        get_constant_or_yield(example_group, :LetDefinitions) do
+          mod = Module.new do
+            include Module.new {
+              example_group.const_set(:NamedSubjectPreventSuper, self)
+            }
+          end
+
+          example_group.const_set(:LetDefinitions, mod)
+          mod
+        end
+      end
+
+      # @private
+      def self.define_helpers_on(example_group)
+        example_group.__send__(:include, module_for(example_group))
+      end
+
+      if Module.method(:const_defined?).arity == 1 # for 1.8
+        # @private
+        #
+        # Gets the named constant or yields.
+        # On 1.8, const_defined? / const_get do not take into
+        # account the inheritance hierarchy.
+        def self.get_constant_or_yield(example_group, name)
+          if example_group.const_defined?(name)
+            example_group.const_get(name)
+          else
+            yield
+          end
+        end
+      else
+        # @private
+        #
+        # Gets the named constant or yields.
+        # On 1.9, const_defined? / const_get take into account the
+        # the inheritance by default, and accept an argument to
+        # disable this behavior. It's important that we don't
+        # consider inheritance here; each example group level that
+        # uses a `let` should get its own `LetDefinitions` module.
+        def self.get_constant_or_yield(example_group, name)
+          if example_group.const_defined?(name, (check_ancestors = false))
+            example_group.const_get(name, check_ancestors)
+          else
+            yield
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/metadata.rb b/rspec-core/lib/rspec/core/metadata.rb
new file mode 100644
index 0000000..6f71c4b
--- /dev/null
+++ b/rspec-core/lib/rspec/core/metadata.rb
@@ -0,0 +1,476 @@
+module RSpec
+  module Core
+    # Each ExampleGroup class and Example instance owns an instance of
+    # Metadata, which is Hash extended to support lazy evaluation of values
+    # associated with keys that may or may not be used by any example or group.
+    #
+    # In addition to metadata that is used internally, this also stores
+    # user-supplied metadata, e.g.
+    #
+    #     describe Something, :type => :ui do
+    #       it "does something", :slow => true do
+    #         # ...
+    #       end
+    #     end
+    #
+    # `:type => :ui` is stored in the Metadata owned by the example group, and
+    # `:slow => true` is stored in the Metadata owned by the example. These can
+    # then be used to select which examples are run using the `--tag` option on
+    # the command line, or several methods on `Configuration` used to filter a
+    # run (e.g. `filter_run_including`, `filter_run_excluding`, etc).
+    #
+    # @see Example#metadata
+    # @see ExampleGroup.metadata
+    # @see FilterManager
+    # @see Configuration#filter_run_including
+    # @see Configuration#filter_run_excluding
+    module Metadata
+      # Matches strings either at the beginning of the input or prefixed with a
+      # whitespace, containing the current path, either postfixed with the
+      # separator, or at the end of the string. Match groups are the character
+      # before and the character after the string if any.
+      #
+      # http://rubular.com/r/fT0gmX6VJX
+      # http://rubular.com/r/duOrD4i3wb
+      # http://rubular.com/r/sbAMHFrOx1
+      def self.relative_path_regex
+        @relative_path_regex ||= /(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/
+      end
+
+      # @api private
+      #
+      # @param line [String] current code line
+      # @return [String] relative path to line
+      def self.relative_path(line)
+        line = line.sub(relative_path_regex, "\\1.\\2".freeze)
+        line = line.sub(/\A([^:]+:\d+)$/, '\\1'.freeze)
+        return nil if line == '-e:1'.freeze
+        line
+      rescue SecurityError
+        nil
+      end
+
+      # @private
+      # Iteratively walks up from the given metadata through all
+      # example group ancestors, yielding each metadata hash along the way.
+      def self.ascending(metadata)
+        yield metadata
+        return unless (group_metadata = metadata.fetch(:example_group) { metadata[:parent_example_group] })
+
+        loop do
+          yield group_metadata
+          break unless (group_metadata = group_metadata[:parent_example_group])
+        end
+      end
+
+      # @private
+      # Returns an enumerator that iteratively walks up the given metadata through all
+      # example group ancestors, yielding each metadata hash along the way.
+      def self.ascend(metadata)
+        enum_for(:ascending, metadata)
+      end
+
+      # @private
+      # Used internally to build a hash from an args array.
+      # Symbols are converted into hash keys with a value of `true`.
+      # This is done to support simple tagging using a symbol, rather
+      # than needing to do `:symbol => true`.
+      def self.build_hash_from(args, warn_about_example_group_filtering=false)
+        hash = args.last.is_a?(Hash) ? args.pop : {}
+
+        hash[args.pop] = true while args.last.is_a?(Symbol)
+
+        if warn_about_example_group_filtering && hash.key?(:example_group)
+          RSpec.deprecate("Filtering by an `:example_group` subhash",
+                          :replacement => "the subhash to filter directly")
+        end
+
+        hash
+      end
+
+      # @private
+      def self.deep_hash_dup(object)
+        return object.dup if Array === object
+        return object unless Hash  === object
+
+        object.inject(object.dup) do |duplicate, (key, value)|
+          duplicate[key] = deep_hash_dup(value)
+          duplicate
+        end
+      end
+
+      # @private
+      def self.backtrace_from(block)
+        return caller unless block.respond_to?(:source_location)
+        [block.source_location.join(':')]
+      end
+
+      # @private
+      # Used internally to populate metadata hashes with computed keys
+      # managed by RSpec.
+      class HashPopulator
+        attr_reader :metadata, :user_metadata, :description_args, :block
+
+        def initialize(metadata, user_metadata, description_args, block)
+          @metadata         = metadata
+          @user_metadata    = user_metadata
+          @description_args = description_args
+          @block            = block
+        end
+
+        def populate
+          ensure_valid_user_keys
+
+          metadata[:execution_result] = Example::ExecutionResult.new
+          metadata[:block]            = block
+          metadata[:description_args] = description_args
+          metadata[:description]      = build_description_from(*metadata[:description_args])
+          metadata[:full_description] = full_description
+          metadata[:described_class]  = described_class
+
+          populate_location_attributes
+          metadata.update(user_metadata)
+          RSpec.configuration.apply_derived_metadata_to(metadata)
+        end
+
+      private
+
+        def populate_location_attributes
+          backtrace = user_metadata.delete(:caller)
+
+          file_path, line_number = if backtrace
+                                     file_path_and_line_number_from(backtrace)
+                                   elsif block.respond_to?(:source_location)
+                                     block.source_location
+                                   else
+                                     file_path_and_line_number_from(caller)
+                                   end
+
+          relative_file_path            = Metadata.relative_path(file_path)
+          metadata[:file_path]          = relative_file_path
+          metadata[:line_number]        = line_number.to_i
+          metadata[:location]           = "#{relative_file_path}:#{line_number}"
+          metadata[:absolute_file_path] = File.expand_path(relative_file_path)
+        end
+
+        def file_path_and_line_number_from(backtrace)
+          first_caller_from_outside_rspec = backtrace.find { |l| l !~ CallerFilter::LIB_REGEX }
+          first_caller_from_outside_rspec ||= backtrace.first
+          /(.+?):(\d+)(?:|:\d+)/.match(first_caller_from_outside_rspec).captures
+        end
+
+        def description_separator(parent_part, child_part)
+          if parent_part.is_a?(Module) && child_part =~ /^(#|::|\.)/
+            ''.freeze
+          else
+            ' '.freeze
+          end
+        end
+
+        def build_description_from(parent_description=nil, my_description=nil)
+          return parent_description.to_s unless my_description
+          separator = description_separator(parent_description, my_description)
+          (parent_description.to_s + separator) << my_description.to_s
+        end
+
+        def ensure_valid_user_keys
+          RESERVED_KEYS.each do |key|
+            next unless user_metadata.key?(key)
+            raise <<-EOM.gsub(/^\s+\|/, '')
+              |#{"*" * 50}
+              |:#{key} is not allowed
+              |
+              |RSpec reserves some hash keys for its own internal use,
+              |including :#{key}, which is used on:
+              |
+              |  #{CallerFilter.first_non_rspec_line}.
+              |
+              |Here are all of RSpec's reserved hash keys:
+              |
+              |  #{RESERVED_KEYS.join("\n  ")}
+              |#{"*" * 50}
+            EOM
+          end
+        end
+      end
+
+      # @private
+      class ExampleHash < HashPopulator
+        def self.create(group_metadata, user_metadata, description, block)
+          example_metadata = group_metadata.dup
+          group_metadata = Hash.new(&ExampleGroupHash.backwards_compatibility_default_proc do |hash|
+            hash[:parent_example_group]
+          end)
+          group_metadata.update(example_metadata)
+
+          example_metadata[:example_group] = group_metadata
+          example_metadata[:shared_group_inclusion_backtrace] = SharedExampleGroupInclusionStackFrame.current_backtrace
+          example_metadata.delete(:parent_example_group)
+
+          description_args = description.nil? ? [] : [description]
+          hash = new(example_metadata, user_metadata, description_args, block)
+          hash.populate
+          hash.metadata
+        end
+
+      private
+
+        def described_class
+          metadata[:example_group][:described_class]
+        end
+
+        def full_description
+          build_description_from(
+            metadata[:example_group][:full_description],
+            metadata[:description]
+          )
+        end
+      end
+
+      # @private
+      class ExampleGroupHash < HashPopulator
+        def self.create(parent_group_metadata, user_metadata, *args, &block)
+          group_metadata = hash_with_backwards_compatibility_default_proc
+
+          if parent_group_metadata
+            group_metadata.update(parent_group_metadata)
+            group_metadata[:parent_example_group] = parent_group_metadata
+          end
+
+          hash = new(group_metadata, user_metadata, args, block)
+          hash.populate
+          hash.metadata
+        end
+
+        def self.hash_with_backwards_compatibility_default_proc
+          Hash.new(&backwards_compatibility_default_proc { |hash| hash })
+        end
+
+        def self.backwards_compatibility_default_proc(&example_group_selector)
+          Proc.new do |hash, key|
+            case key
+            when :example_group
+              # We commonly get here when rspec-core is applying a previously
+              # configured filter rule, such as when a gem configures:
+              #
+              #   RSpec.configure do |c|
+              #     c.include MyGemHelpers, :example_group => { :file_path => /spec\/my_gem_specs/ }
+              #   end
+              #
+              # It's confusing for a user to get a deprecation at this point in
+              # the code, so instead we issue a deprecation from the config APIs
+              # that take a metadata hash, and MetadataFilter sets this thread
+              # local to silence the warning here since it would be so
+              # confusing.
+              unless RSpec.thread_local_metadata[:silence_metadata_example_group_deprecations]
+                RSpec.deprecate("The `:example_group` key in an example group's metadata hash",
+                                :replacement => "the example group's hash directly for the " \
+                                "computed keys and `:parent_example_group` to access the parent " \
+                                "example group metadata")
+              end
+
+              group_hash = example_group_selector.call(hash)
+              LegacyExampleGroupHash.new(group_hash) if group_hash
+            when :example_group_block
+              RSpec.deprecate("`metadata[:example_group_block]`",
+                              :replacement => "`metadata[:block]`")
+              hash[:block]
+            when :describes
+              RSpec.deprecate("`metadata[:describes]`",
+                              :replacement => "`metadata[:described_class]`")
+              hash[:described_class]
+            end
+          end
+        end
+
+      private
+
+        def described_class
+          candidate = metadata[:description_args].first
+          return candidate unless NilClass === candidate || String === candidate
+          parent_group = metadata[:parent_example_group]
+          parent_group && parent_group[:described_class]
+        end
+
+        def full_description
+          description          = metadata[:description]
+          parent_example_group = metadata[:parent_example_group]
+          return description unless parent_example_group
+
+          parent_description   = parent_example_group[:full_description]
+          separator = description_separator(parent_example_group[:description_args].last,
+                                            metadata[:description_args].first)
+
+          parent_description + separator + description
+        end
+      end
+
+      # @private
+      RESERVED_KEYS = [
+        :description,
+        :example_group,
+        :parent_example_group,
+        :execution_result,
+        :file_path,
+        :absolute_file_path,
+        :full_description,
+        :line_number,
+        :location,
+        :block
+      ]
+    end
+
+    # Mixin that makes the including class imitate a hash for backwards
+    # compatibility. The including class should use `attr_accessor` to
+    # declare attributes.
+    # @private
+    module HashImitatable
+      def self.included(klass)
+        klass.extend ClassMethods
+      end
+
+      def to_h
+        hash = extra_hash_attributes.dup
+
+        self.class.hash_attribute_names.each do |name|
+          hash[name] = __send__(name)
+        end
+
+        hash
+      end
+
+      (Hash.public_instance_methods - Object.public_instance_methods).each do |method_name|
+        next if [:[], :[]=, :to_h].include?(method_name.to_sym)
+
+        define_method(method_name) do |*args, &block|
+          issue_deprecation(method_name, *args)
+
+          hash = hash_for_delegation
+          self.class.hash_attribute_names.each do |name|
+            hash.delete(name) unless instance_variable_defined?(:"@#{name}")
+          end
+
+          hash.__send__(method_name, *args, &block).tap do
+            # apply mutations back to the object
+            hash.each do |name, value|
+              if directly_supports_attribute?(name)
+                set_value(name, value)
+              else
+                extra_hash_attributes[name] = value
+              end
+            end
+          end
+        end
+      end
+
+      def [](key)
+        issue_deprecation(:[], key)
+
+        if directly_supports_attribute?(key)
+          get_value(key)
+        else
+          extra_hash_attributes[key]
+        end
+      end
+
+      def []=(key, value)
+        issue_deprecation(:[]=, key, value)
+
+        if directly_supports_attribute?(key)
+          set_value(key, value)
+        else
+          extra_hash_attributes[key] = value
+        end
+      end
+
+    private
+
+      def extra_hash_attributes
+        @extra_hash_attributes ||= {}
+      end
+
+      def directly_supports_attribute?(name)
+        self.class.hash_attribute_names.include?(name)
+      end
+
+      def get_value(name)
+        __send__(name)
+      end
+
+      def set_value(name, value)
+        __send__(:"#{name}=", value)
+      end
+
+      def hash_for_delegation
+        to_h
+      end
+
+      def issue_deprecation(_method_name, *_args)
+        # no-op by default: subclasses can override
+      end
+
+      # @private
+      module ClassMethods
+        def hash_attribute_names
+          @hash_attribute_names ||= []
+        end
+
+        def attr_accessor(*names)
+          hash_attribute_names.concat(names)
+          super
+        end
+      end
+    end
+
+    # @private
+    # Together with the example group metadata hash default block,
+    # provides backwards compatibility for the old `:example_group`
+    # key. In RSpec 2.x, the computed keys of a group's metadata
+    # were exposed from a nested subhash keyed by `[:example_group]`, and
+    # then the parent group's metadata was exposed by sub-subhash
+    # keyed by `[:example_group][:example_group]`.
+    #
+    # In RSpec 3, we reorganized this to that the computed keys are
+    # exposed directly of the group metadata hash (no nesting), and
+    # `:parent_example_group` returns the parent group's metadata.
+    #
+    # Maintaining backwards compatibility was difficult: we wanted
+    # `:example_group` to return an object that:
+    #
+    #   * Exposes the top-level metadata keys that used to be nested
+    #     under `:example_group`.
+    #   * Supports mutation (rspec-rails, for example, assigns
+    #     `metadata[:example_group][:described_class]` when you use
+    #     anonymous controller specs) such that changes are written
+    #     back to the top-level metadata hash.
+    #   * Exposes the parent group metadata as
+    #     `[:example_group][:example_group]`.
+    class LegacyExampleGroupHash
+      include HashImitatable
+
+      def initialize(metadata)
+        @metadata = metadata
+        parent_group_metadata = metadata.fetch(:parent_example_group) { {} }[:example_group]
+        self[:example_group] = parent_group_metadata if parent_group_metadata
+      end
+
+      def to_h
+        super.merge(@metadata)
+      end
+
+    private
+
+      def directly_supports_attribute?(name)
+        name != :example_group
+      end
+
+      def get_value(name)
+        @metadata[name]
+      end
+
+      def set_value(name, value)
+        @metadata[name] = value
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/metadata_filter.rb b/rspec-core/lib/rspec/core/metadata_filter.rb
new file mode 100644
index 0000000..ffe8c86
--- /dev/null
+++ b/rspec-core/lib/rspec/core/metadata_filter.rb
@@ -0,0 +1,222 @@
+module RSpec
+  module Core
+    # Contains metadata filtering logic. This has been extracted from
+    # the metadata classes because it operates ON a metadata hash but
+    # does not manage any of the state in the hash. We're moving towards
+    # having metadata be a raw hash (not a custom subclass), so externalizing
+    # this filtering logic helps us move in that direction.
+    module MetadataFilter
+      class << self
+        # @private
+        def apply?(predicate, filters, metadata)
+          filters.__send__(predicate) { |k, v| filter_applies?(k, v, metadata) }
+        end
+
+        # @private
+        def filter_applies?(key, value, metadata)
+          silence_metadata_example_group_deprecations do
+            return filter_applies_to_any_value?(key, value, metadata) if Array === metadata[key] && !(Proc === value)
+            return location_filter_applies?(value, metadata)          if key == :locations
+            return filters_apply?(key, value, metadata)               if Hash === value
+
+            return false unless metadata.key?(key)
+
+            case value
+            when Regexp
+              metadata[key] =~ value
+            when Proc
+              case value.arity
+              when 0 then value.call
+              when 2 then value.call(metadata[key], metadata)
+              else value.call(metadata[key])
+              end
+            else
+              metadata[key].to_s == value.to_s
+            end
+          end
+        end
+
+      private
+
+        def filter_applies_to_any_value?(key, value, metadata)
+          metadata[key].any? { |v| filter_applies?(key, v,  key => value) }
+        end
+
+        def location_filter_applies?(locations, metadata)
+          line_numbers = example_group_declaration_lines(locations, metadata)
+          line_numbers.empty? || line_number_filter_applies?(line_numbers, metadata)
+        end
+
+        def line_number_filter_applies?(line_numbers, metadata)
+          preceding_declaration_lines = line_numbers.map { |n| RSpec.world.preceding_declaration_line(n) }
+          !(relevant_line_numbers(metadata) & preceding_declaration_lines).empty?
+        end
+
+        def relevant_line_numbers(metadata)
+          Metadata.ascend(metadata).map { |meta| meta[:line_number] }
+        end
+
+        def example_group_declaration_lines(locations, metadata)
+          FlatMap.flat_map(Metadata.ascend(metadata)) do |meta|
+            locations[meta[:absolute_file_path]]
+          end.uniq
+        end
+
+        def filters_apply?(key, value, metadata)
+          subhash = metadata[key]
+          return false unless Hash === subhash || HashImitatable === subhash
+          value.all? { |k, v| filter_applies?(k, v, subhash) }
+        end
+
+        def silence_metadata_example_group_deprecations
+          RSpec.thread_local_metadata[:silence_metadata_example_group_deprecations] = true
+          yield
+        ensure
+          RSpec.thread_local_metadata.delete(:silence_metadata_example_group_deprecations)
+        end
+      end
+    end
+
+    # Tracks a collection of filterable items (e.g. modules, hooks, etc)
+    # and provides an optimized API to get the applicable items for the
+    # metadata of an example or example group.
+    #
+    # There are two implementations, optimized for different uses.
+    # @private
+    module FilterableItemRepository
+      # This implementation is simple, and is optimized for frequent
+      # updates but rare queries. `append` and `prepend` do no extra
+      # processing, and no internal memoization is done, since this
+      # is not optimized for queries.
+      #
+      # This is ideal for use by a example or example group, which may
+      # be updated multiple times with globally configured hooks, etc,
+      # but will not be queried frequently by other examples or examle
+      # groups.
+      # @private
+      class UpdateOptimized
+        attr_reader :items_and_filters
+
+        def initialize(applies_predicate)
+          @applies_predicate = applies_predicate
+          @items_and_filters = []
+        end
+
+        def append(item, metadata)
+          @items_and_filters << [item, metadata]
+        end
+
+        def prepend(item, metadata)
+          @items_and_filters.unshift [item, metadata]
+        end
+
+        def items_for(request_meta)
+          @items_and_filters.each_with_object([]) do |(item, item_meta), to_return|
+            to_return << item if item_meta.empty? ||
+                                 MetadataFilter.apply?(@applies_predicate, item_meta, request_meta)
+          end
+        end
+
+        unless [].respond_to?(:each_with_object) # For 1.8.7
+          undef items_for
+          def items_for(request_meta)
+            @items_and_filters.inject([]) do |to_return, (item, item_meta)|
+              to_return << item if item_meta.empty? ||
+                                   MetadataFilter.apply?(@applies_predicate, item_meta, request_meta)
+              to_return
+            end
+          end
+        end
+      end
+
+      # This implementation is much more complex, and is optimized for
+      # rare (or hopefully no) updates once the queries start. Updates
+      # incur a cost as it has to clear the memoization and keep track
+      # of applicable keys. Queries will be O(N) the first time an item
+      # is provided with a given set of applicable metadata; subsequent
+      # queries with items with the same set of applicable metadata will
+      # be O(1) due to internal memoization.
+      #
+      # This is ideal for use by config, where filterable items (e.g. hooks)
+      # are typically added at the start of the process (e.g. in `spec_helper`)
+      # and then repeatedly queried as example groups and examples are defined.
+      # @private
+      class QueryOptimized < UpdateOptimized
+        alias find_items_for items_for
+        private :find_items_for
+
+        def initialize(applies_predicate)
+          super
+          @applicable_keys   = Set.new
+          @proc_keys         = Set.new
+          @memoized_lookups  = Hash.new do |hash, applicable_metadata|
+            hash[applicable_metadata] = find_items_for(applicable_metadata)
+          end
+        end
+
+        def append(item, metadata)
+          super
+          handle_mutation(metadata)
+        end
+
+        def prepend(item, metadata)
+          super
+          handle_mutation(metadata)
+        end
+
+        def items_for(metadata)
+          # The filtering of `metadata` to `applicable_metadata` is the key thing
+          # that makes the memoization actually useful in practice, since each
+          # example and example group have different metadata (e.g. location and
+          # description). By filtering to the metadata keys our items care about,
+          # we can ignore extra metadata keys that differ for each example/group.
+          # For example, given `config.include DBHelpers, :db`, example groups
+          # can be split into these two sets: those that are tagged with `:db` and those
+          # that are not. For each set, this method for the first group in the set is
+          # still an `O(N)` calculation, but all subsequent groups in the set will be
+          # constant time lookups when they call this method.
+          applicable_metadata = applicable_metadata_from(metadata)
+
+          if applicable_metadata.any? { |k, _| @proc_keys.include?(k) }
+            # It's unsafe to memoize lookups involving procs (since they can
+            # be non-deterministic), so we skip the memoization in this case.
+            find_items_for(applicable_metadata)
+          else
+            @memoized_lookups[applicable_metadata]
+          end
+        end
+
+      private
+
+        def handle_mutation(metadata)
+          @applicable_keys.merge(metadata.keys)
+          @proc_keys.merge(proc_keys_from metadata)
+          @memoized_lookups.clear
+        end
+
+        def applicable_metadata_from(metadata)
+          @applicable_keys.inject({}) do |hash, key|
+            hash[key] = metadata[key] if metadata.key?(key)
+            hash
+          end
+        end
+
+        def proc_keys_from(metadata)
+          metadata.each_with_object([]) do |(key, value), to_return|
+            to_return << key if Proc === value
+          end
+        end
+
+        unless [].respond_to?(:each_with_object) # For 1.8.7
+          undef proc_keys_from
+          def proc_keys_from(metadata)
+            metadata.inject([]) do |to_return, (key, value)|
+              to_return << key if Proc === value
+              to_return
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/minitest_assertions_adapter.rb b/rspec-core/lib/rspec/core/minitest_assertions_adapter.rb
new file mode 100644
index 0000000..25db751
--- /dev/null
+++ b/rspec-core/lib/rspec/core/minitest_assertions_adapter.rb
@@ -0,0 +1,31 @@
+begin
+  # Only the minitest 5.x gem includes the minitest.rb and assertions.rb files.
+  require 'minitest'
+  require 'minitest/assertions'
+rescue LoadError
+  # We must be using Ruby Core's MiniTest or the Minitest gem 4.x.
+  require 'minitest/unit'
+  Minitest = MiniTest
+end
+
+module RSpec
+  module Core
+    # @private
+    module MinitestAssertionsAdapter
+      include ::Minitest::Assertions
+      # Need to forcefully include Pending after Minitest::Assertions
+      # to make sure our own #skip method beats Minitest's.
+      include ::RSpec::Core::Pending
+
+      # Minitest 5.x requires this accessor to be available. See
+      # https://github.com/seattlerb/minitest/blob/38f0a5fcbd9c37c3f80a3eaad4ba84d3fc9947a0/lib/minitest/assertions.rb#L8
+      #
+      # It is not required for other extension libraries, and RSpec does not
+      # report or make this information available to formatters.
+      attr_writer :assertions
+      def assertions
+        @assertions ||= 0
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/mocking_adapters/flexmock.rb b/rspec-core/lib/rspec/core/mocking_adapters/flexmock.rb
new file mode 100644
index 0000000..91475ae
--- /dev/null
+++ b/rspec-core/lib/rspec/core/mocking_adapters/flexmock.rb
@@ -0,0 +1,31 @@
+#  Created by Jim Weirich on 2007-04-10.
+#  Copyright (c) 2007. All rights reserved.
+
+require 'flexmock/rspec'
+
+module RSpec
+  module Core
+    module MockingAdapters
+      # @private
+      module Flexmock
+        include ::FlexMock::MockContainer
+
+        def self.framework_name
+          :flexmock
+        end
+
+        def setup_mocks_for_rspec
+          # No setup required.
+        end
+
+        def verify_mocks_for_rspec
+          flexmock_verify
+        end
+
+        def teardown_mocks_for_rspec
+          flexmock_close
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/mocking_adapters/mocha.rb b/rspec-core/lib/rspec/core/mocking_adapters/mocha.rb
new file mode 100644
index 0000000..8caf7b6
--- /dev/null
+++ b/rspec-core/lib/rspec/core/mocking_adapters/mocha.rb
@@ -0,0 +1,57 @@
+# In order to support all versions of mocha, we have to jump through some
+# hoops here.
+#
+# mocha >= '0.13.0':
+#   require 'mocha/api' is required.
+#   require 'mocha/object' raises a LoadError b/c the file no longer exists.
+# mocha < '0.13.0', >= '0.9.7'
+#   require 'mocha/api' is required.
+#   require 'mocha/object' is required.
+# mocha < '0.9.7':
+#   require 'mocha/api' raises a LoadError b/c the file does not yet exist.
+#   require 'mocha/standalone' is required.
+#   require 'mocha/object' is required.
+begin
+  require 'mocha/api'
+
+  begin
+    require 'mocha/object'
+  rescue LoadError
+    # Mocha >= 0.13.0 no longer contains this file nor needs it to be loaded.
+  end
+rescue LoadError
+  require 'mocha/standalone'
+  require 'mocha/object'
+end
+
+module RSpec
+  module Core
+    module MockingAdapters
+      # @private
+      module Mocha
+        def self.framework_name
+          :mocha
+        end
+
+        # Mocha::Standalone was deprecated as of Mocha 0.9.7.
+        begin
+          include ::Mocha::API
+        rescue NameError
+          include ::Mocha::Standalone
+        end
+
+        def setup_mocks_for_rspec
+          mocha_setup
+        end
+
+        def verify_mocks_for_rspec
+          mocha_verify
+        end
+
+        def teardown_mocks_for_rspec
+          mocha_teardown
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/mocking_adapters/null.rb b/rspec-core/lib/rspec/core/mocking_adapters/null.rb
new file mode 100644
index 0000000..442de9a
--- /dev/null
+++ b/rspec-core/lib/rspec/core/mocking_adapters/null.rb
@@ -0,0 +1,14 @@
+module RSpec
+  module Core
+    module MockingAdapters
+      # @private
+      module Null
+        def setup_mocks_for_rspec; end
+
+        def verify_mocks_for_rspec; end
+
+        def teardown_mocks_for_rspec; end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/mocking_adapters/rr.rb b/rspec-core/lib/rspec/core/mocking_adapters/rr.rb
new file mode 100644
index 0000000..d72651a
--- /dev/null
+++ b/rspec-core/lib/rspec/core/mocking_adapters/rr.rb
@@ -0,0 +1,31 @@
+require 'rr'
+
+RSpec.configuration.backtrace_exclusion_patterns.push(RR::Errors::BACKTRACE_IDENTIFIER)
+
+module RSpec
+  module Core
+    # @private
+    module MockingAdapters
+      # @private
+      module RR
+        def self.framework_name
+          :rr
+        end
+
+        include ::RR::Extensions::InstanceMethods
+
+        def setup_mocks_for_rspec
+          ::RR::Space.instance.reset
+        end
+
+        def verify_mocks_for_rspec
+          ::RR::Space.instance.verify_doubles
+        end
+
+        def teardown_mocks_for_rspec
+          ::RR::Space.instance.reset
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/mocking_adapters/rspec.rb b/rspec-core/lib/rspec/core/mocking_adapters/rspec.rb
new file mode 100644
index 0000000..bb3f0ae
--- /dev/null
+++ b/rspec-core/lib/rspec/core/mocking_adapters/rspec.rb
@@ -0,0 +1,32 @@
+require 'rspec/mocks'
+
+module RSpec
+  module Core
+    module MockingAdapters
+      # @private
+      module RSpec
+        include ::RSpec::Mocks::ExampleMethods
+
+        def self.framework_name
+          :rspec
+        end
+
+        def self.configuration
+          ::RSpec::Mocks.configuration
+        end
+
+        def setup_mocks_for_rspec
+          ::RSpec::Mocks.setup
+        end
+
+        def verify_mocks_for_rspec
+          ::RSpec::Mocks.verify
+        end
+
+        def teardown_mocks_for_rspec
+          ::RSpec::Mocks.teardown
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/notifications.rb b/rspec-core/lib/rspec/core/notifications.rb
new file mode 100644
index 0000000..50355d2
--- /dev/null
+++ b/rspec-core/lib/rspec/core/notifications.rb
@@ -0,0 +1,603 @@
+RSpec::Support.require_rspec_core "formatters/helpers"
+RSpec::Support.require_rspec_support "encoded_string"
+
+module RSpec::Core
+  # Notifications are value objects passed to formatters to provide them
+  # with information about a particular event of interest.
+  module Notifications
+    # @private
+    module NullColorizer
+      module_function
+      def wrap(line, _code_or_symbol)
+        line
+      end
+    end
+
+    # The `StartNotification` represents a notification sent by the reporter
+    # when the suite is started. It contains the expected amount of examples
+    # to be executed, and the load time of RSpec.
+    #
+    # @attr count [Fixnum] the number counted
+    # @attr load_time [Float] the number of seconds taken to boot RSpec
+    #                         and load the spec files
+    StartNotification = Struct.new(:count, :load_time)
+
+    # The `ExampleNotification` represents notifications sent by the reporter
+    # which contain information about the current (or soon to be) example.
+    # It is used by formatters to access information about that example.
+    #
+    # @example
+    #   def example_started(notification)
+    #     puts "Hey I started #{notification.example.description}"
+    #   end
+    #
+    # @attr example [RSpec::Core::Example] the current example
+    ExampleNotification = Struct.new(:example)
+    class ExampleNotification
+      # @private
+      def self.for(example)
+        execution_result = example.execution_result
+
+        if execution_result.pending_fixed?
+          PendingExampleFixedNotification.new(example)
+        elsif execution_result.example_skipped?
+          SkippedExampleNotification.new(example)
+        elsif execution_result.status == :pending
+          PendingExampleFailedAsExpectedNotification.new(example)
+        elsif execution_result.status == :failed
+          FailedExampleNotification.new(example)
+        else
+          new(example)
+        end
+      end
+
+      private_class_method :new
+    end
+
+    # The `ExamplesNotification` represents notifications sent by the reporter
+    # which contain information about the suites examples.
+    #
+    # @example
+    #   def stop(notification)
+    #     puts "Hey I ran #{notification.examples.size}"
+    #   end
+    #
+    class ExamplesNotification
+      def initialize(reporter)
+        @reporter = reporter
+      end
+
+      # @return [Array<RSpec::Core::Example>] list of examples
+      def examples
+        @reporter.examples
+      end
+
+      # @return [Array<RSpec::Core::Example>] list of failed examples
+      def failed_examples
+        @reporter.failed_examples
+      end
+
+      # @return [Array<RSpec::Core::Example>] list of pending examples
+      def pending_examples
+        @reporter.pending_examples
+      end
+
+      # @return [Array<RSpec::Core::Notifications::ExampleNotification>]
+      #         returns examples as notifications
+      def notifications
+        @notifications ||= format_examples(examples)
+      end
+
+      # @return [Array<RSpec::Core::Notifications::FailedExampleNotification>]
+      #         returns failed examples as notifications
+      def failure_notifications
+        @failed_notifications ||= format_examples(failed_examples)
+      end
+
+      # @return [Array<RSpec::Core::Notifications::SkippedExampleNotification,
+      #                 RSpec::Core::Notifications::PendingExampleFailedAsExpectedNotification>]
+      #         returns pending examples as notifications
+      def pending_notifications
+        @pending_notifications ||= format_examples(pending_examples)
+      end
+
+      # @return [String] The list of failed examples, fully formatted in the way
+      #   that RSpec's built-in formatters emit.
+      def fully_formatted_failed_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        formatted = "\nFailures:\n"
+
+        failure_notifications.each_with_index do |failure, index|
+          formatted << failure.fully_formatted(index.next, colorizer)
+        end
+
+        formatted
+      end
+
+      # @return [String] The list of pending examples, fully formatted in the
+      #   way that RSpec's built-in formatters emit.
+      def fully_formatted_pending_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        formatted = "\nPending: (Failures listed here are expected and do not affect your suite's status)\n"
+
+        pending_notifications.each_with_index do |notification, index|
+          formatted << notification.fully_formatted(index.next, colorizer)
+        end
+
+        formatted
+      end
+
+    private
+
+      def format_examples(examples)
+        examples.map do |example|
+          ExampleNotification.for(example)
+        end
+      end
+    end
+
+    # The `FailedExampleNotification` extends `ExampleNotification` with
+    # things useful for failed specs.
+    #
+    # @example
+    #   def example_failed(notification)
+    #     puts "Hey I failed :("
+    #     puts "Here's my stack trace"
+    #     puts notification.exception.backtrace.join("\n")
+    #   end
+    #
+    # @attr [RSpec::Core::Example] example the current example
+    # @see ExampleNotification
+    class FailedExampleNotification < ExampleNotification
+      public_class_method :new
+
+      # @return [Exception] The example failure
+      def exception
+        example.execution_result.exception
+      end
+
+      # @return [String] The example description
+      def description
+        example.full_description
+      end
+
+      # Returns the message generated for this failure line by line.
+      #
+      # @return [Array<String>] The example failure message
+      def message_lines
+        add_shared_group_lines(failure_lines, NullColorizer)
+      end
+
+      # Returns the message generated for this failure colorized line by line.
+      #
+      # @param colorizer [#wrap] An object to colorize the message_lines by
+      # @return [Array<String>] The example failure message colorized
+      def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        add_shared_group_lines(failure_lines, colorizer).map do |line|
+          colorizer.wrap line, message_color
+        end
+      end
+
+      # Returns the failures formatted backtrace.
+      #
+      # @return [Array<String>] the examples backtrace lines
+      def formatted_backtrace
+        backtrace_formatter.format_backtrace(exception.backtrace, example.metadata)
+      end
+
+      # Returns the failures colorized formatted backtrace.
+      #
+      # @param colorizer [#wrap] An object to colorize the message_lines by
+      # @return [Array<String>] the examples colorized backtrace lines
+      def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        formatted_backtrace.map do |backtrace_info|
+          colorizer.wrap "# #{backtrace_info}", RSpec.configuration.detail_color
+        end
+      end
+
+      # @return [String] The failure information fully formatted in the way that
+      #   RSpec's built-in formatters emit.
+      def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        "\n  #{failure_number}) #{description}\n#{formatted_message_and_backtrace(colorizer)}"
+      end
+
+    private
+
+      if String.method_defined?(:encoding)
+        def encoding_of(string)
+          string.encoding
+        end
+      else
+        def encoding_of(_string)
+        end
+      end
+
+      def backtrace_formatter
+        RSpec.configuration.backtrace_formatter
+      end
+
+      def exception_class_name
+        name = exception.class.name.to_s
+        name = "(anonymous error class)" if name == ''
+        name
+      end
+
+      def failure_lines
+        @failure_lines ||=
+          begin
+            lines = ["Failure/Error: #{read_failed_line.strip}"]
+            lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/
+            exception.message.to_s.split("\n").each do |line|
+              lines << "  #{line}" if exception.message
+            end
+            lines
+          end
+      end
+
+      def add_shared_group_lines(lines, colorizer)
+        example.metadata[:shared_group_inclusion_backtrace].each do |frame|
+          lines << colorizer.wrap(frame.description, RSpec.configuration.default_color)
+        end
+
+        lines
+      end
+
+      def read_failed_line
+        matching_line = find_failed_line
+        unless matching_line
+          return "Unable to find matching line from backtrace"
+        end
+
+        file_path, line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)[1..2]
+
+        if File.exist?(file_path)
+          File.readlines(file_path)[line_number.to_i - 1] ||
+            "Unable to find matching line in #{file_path}"
+        else
+          "Unable to find #{file_path} to read failed line"
+        end
+      rescue SecurityError
+        "Unable to read failed line"
+      end
+
+      def find_failed_line
+        example_path = example.metadata[:absolute_file_path].downcase
+        exception.backtrace.find do |line|
+          next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
+          File.expand_path(line_path).downcase == example_path
+        end
+      end
+
+      def formatted_message_and_backtrace(colorizer)
+        formatted = ""
+
+        colorized_message_lines(colorizer).each do |line|
+          formatted << RSpec::Support::EncodedString.new("     #{line}\n", encoding_of(formatted))
+        end
+
+        colorized_formatted_backtrace(colorizer).each do |line|
+          formatted << RSpec::Support::EncodedString.new("     #{line}\n", encoding_of(formatted))
+        end
+
+        formatted
+      end
+
+      def message_color
+        RSpec.configuration.failure_color
+      end
+    end
+
+    # The `PendingExampleFixedNotification` extends `ExampleNotification` with
+    # things useful for specs that pass when they are expected to fail.
+    #
+    # @attr [RSpec::Core::Example] example the current example
+    # @see ExampleNotification
+    class PendingExampleFixedNotification < FailedExampleNotification
+      public_class_method :new
+
+      # Returns the examples description.
+      #
+      # @return [String] The example description
+      def description
+        "#{example.full_description} FIXED"
+      end
+
+      # Returns the message generated for this failure line by line.
+      #
+      # @return [Array<String>] The example failure message
+      def message_lines
+        ["Expected pending '#{example.execution_result.pending_message}' to fail. No Error was raised."]
+      end
+
+      # Returns the message generated for this failure colorized line by line.
+      #
+      # @param colorizer [#wrap] An object to colorize the message_lines by
+      # @return [Array<String>] The example failure message colorized
+      def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        message_lines.map { |line| colorizer.wrap(line, RSpec.configuration.fixed_color) }
+      end
+    end
+
+    # @private
+    module PendingExampleNotificationMethods
+    private
+
+      def fully_formatted_header(pending_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        colorizer.wrap("\n  #{pending_number}) #{example.full_description}\n", :pending) <<
+        colorizer.wrap("     # #{example.execution_result.pending_message}\n", :detail)
+      end
+    end
+
+    # The `PendingExampleFailedAsExpectedNotification` extends `FailedExampleNotification` with
+    # things useful for pending specs that fail as expected.
+    #
+    # @attr [RSpec::Core::Example] example the current example
+    # @see ExampleNotification
+    class PendingExampleFailedAsExpectedNotification < FailedExampleNotification
+      include PendingExampleNotificationMethods
+      public_class_method :new
+
+      # @return [Exception] The exception that occurred while the pending example was executed
+      def exception
+        example.execution_result.pending_exception
+      end
+
+      # @return [String] The pending detail fully formatted in the way that
+      #   RSpec's built-in formatters emit.
+      def fully_formatted(pending_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        fully_formatted_header(pending_number, colorizer) << formatted_message_and_backtrace(colorizer)
+      end
+
+    private
+
+      def message_color
+        RSpec.configuration.pending_color
+      end
+    end
+
+    # The `SkippedExampleNotification` extends `ExampleNotification` with
+    # things useful for specs that are skipped.
+    #
+    # @attr [RSpec::Core::Example] example the current example
+    # @see ExampleNotification
+    class SkippedExampleNotification < ExampleNotification
+      include PendingExampleNotificationMethods
+      public_class_method :new
+
+      # @return [String] The pending detail fully formatted in the way that
+      #   RSpec's built-in formatters emit.
+      def fully_formatted(pending_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        formatted_caller = RSpec.configuration.backtrace_formatter.backtrace_line(example.location)
+        fully_formatted_header(pending_number, colorizer) << colorizer.wrap("     # #{formatted_caller}\n", :detail)
+      end
+    end
+
+    # The `GroupNotification` represents notifications sent by the reporter
+    # which contain information about the currently running (or soon to be)
+    # example group. It is used by formatters to access information about that
+    # group.
+    #
+    # @example
+    #   def example_group_started(notification)
+    #     puts "Hey I started #{notification.group.description}"
+    #   end
+    # @attr group [RSpec::Core::ExampleGroup] the current group
+    GroupNotification = Struct.new(:group)
+
+    # The `MessageNotification` encapsulates generic messages that the reporter
+    # sends to formatters.
+    #
+    # @attr message [String] the message
+    MessageNotification = Struct.new(:message)
+
+    # The `SeedNotification` holds the seed used to randomize examples and
+    # whether that seed has been used or not.
+    #
+    # @attr seed [Fixnum] the seed used to randomize ordering
+    # @attr used [Boolean] whether the seed has been used or not
+    SeedNotification = Struct.new(:seed, :used)
+    class SeedNotification
+      # @api
+      # @return [Boolean] has the seed been used?
+      def seed_used?
+        !!used
+      end
+      private :used
+
+      # @return [String] The seed information fully formatted in the way that
+      #   RSpec's built-in formatters emit.
+      def fully_formatted
+        "\nRandomized with seed #{seed}\n"
+      end
+    end
+
+    # The `SummaryNotification` holds information about the results of running
+    # a test suite. It is used by formatters to provide information at the end
+    # of the test run.
+    #
+    # @attr duration [Float] the time taken (in seconds) to run the suite
+    # @attr examples [Array<RSpec::Core::Example>] the examples run
+    # @attr failed_examples [Array<RSpec::Core::Example>] the failed examples
+    # @attr pending_examples [Array<RSpec::Core::Example>] the pending examples
+    # @attr load_time [Float] the number of seconds taken to boot RSpec
+    #                         and load the spec files
+    SummaryNotification = Struct.new(:duration, :examples, :failed_examples, :pending_examples, :load_time)
+    class SummaryNotification
+      # @api
+      # @return [Fixnum] the number of examples run
+      def example_count
+        @example_count ||= examples.size
+      end
+
+      # @api
+      # @return [Fixnum] the number of failed examples
+      def failure_count
+        @failure_count ||= failed_examples.size
+      end
+
+      # @api
+      # @return [Fixnum] the number of pending examples
+      def pending_count
+        @pending_count ||= pending_examples.size
+      end
+
+      # @api
+      # @return [String] A line summarising the result totals of the spec run.
+      def totals_line
+        summary = Formatters::Helpers.pluralize(example_count, "example")
+        summary << ", " << Formatters::Helpers.pluralize(failure_count, "failure")
+        summary << ", #{pending_count} pending" if pending_count > 0
+        summary
+      end
+
+      # @api public
+      #
+      # Wraps the results line with colors based on the configured
+      # colors for failure, pending, and success. Defaults to red,
+      # yellow, green accordingly.
+      #
+      # @param colorizer [#wrap] An object which supports wrapping text with
+      #                          specific colors.
+      # @return [String] A colorized results line.
+      def colorized_totals_line(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        if failure_count > 0
+          colorizer.wrap(totals_line, RSpec.configuration.failure_color)
+        elsif pending_count > 0
+          colorizer.wrap(totals_line, RSpec.configuration.pending_color)
+        else
+          colorizer.wrap(totals_line, RSpec.configuration.success_color)
+        end
+      end
+
+      # @api public
+      #
+      # Formats failures into a rerunable command format.
+      #
+      # @param colorizer [#wrap] An object which supports wrapping text with
+      #                          specific colors.
+      # @return [String] A colorized summary line.
+      def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        "\nFailed examples:\n\n" +
+        failed_examples.map do |example|
+          colorizer.wrap("rspec #{example.rerun_argument}", RSpec.configuration.failure_color) + " " +
+          colorizer.wrap("# #{example.full_description}",   RSpec.configuration.detail_color)
+        end.join("\n")
+      end
+
+      # @return [String] a formatted version of the time it took to run the
+      #   suite
+      def formatted_duration
+        Formatters::Helpers.format_duration(duration)
+      end
+
+      # @return [String] a formatted version of the time it took to boot RSpec
+      #   and load the spec files
+      def formatted_load_time
+        Formatters::Helpers.format_duration(load_time)
+      end
+
+      # @return [String] The summary information fully formatted in the way that
+      #   RSpec's built-in formatters emit.
+      def fully_formatted(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
+        formatted = "\nFinished in #{formatted_duration} " \
+                    "(files took #{formatted_load_time} to load)\n" \
+                    "#{colorized_totals_line(colorizer)}\n"
+
+        unless failed_examples.empty?
+          formatted << colorized_rerun_commands(colorizer) << "\n"
+        end
+
+        formatted
+      end
+    end
+
+    # The `ProfileNotification` holds information about the results of running a
+    # test suite when profiling is enabled. It is used by formatters to provide
+    # information at the end of the test run for profiling information.
+    #
+    # @attr duration [Float] the time taken (in seconds) to run the suite
+    # @attr examples [Array<RSpec::Core::Example>] the examples run
+    # @attr number_of_examples [Fixnum] the number of examples to profile
+    ProfileNotification = Struct.new(:duration, :examples, :number_of_examples)
+    class ProfileNotification
+      # @return [Array<RSpec::Core::Example>] the slowest examples
+      def slowest_examples
+        @slowest_examples ||=
+          examples.sort_by do |example|
+            -example.execution_result.run_time
+          end.first(number_of_examples)
+      end
+
+      # @return [Float] the time taken (in seconds) to run the slowest examples
+      def slow_duration
+        @slow_duration ||=
+          slowest_examples.inject(0.0) do |i, e|
+            i + e.execution_result.run_time
+          end
+      end
+
+      # @return [String] the percentage of total time taken
+      def percentage
+        @percentage ||=
+          begin
+            time_taken = slow_duration / duration
+            '%.1f' % ((time_taken.nan? ? 0.0 : time_taken) * 100)
+          end
+      end
+
+      # @return [Array<RSpec::Core::Example>] the slowest example groups
+      def slowest_groups
+        @slowest_groups ||= calculate_slowest_groups
+      end
+
+    private
+
+      def calculate_slowest_groups
+        example_groups = {}
+
+        examples.each do |example|
+          location = example.example_group.parent_groups.last.metadata[:location]
+
+          location_hash = example_groups[location] ||= Hash.new(0)
+          location_hash[:total_time]  += example.execution_result.run_time
+          location_hash[:count]       += 1
+          next if location_hash.key?(:description)
+          location_hash[:description] = example.example_group.top_level_description
+        end
+
+        # stop if we've only one example group
+        return {} if example_groups.keys.length <= 1
+
+        example_groups.each_value do |hash|
+          hash[:average] = hash[:total_time].to_f / hash[:count]
+        end
+
+        example_groups.sort_by { |_, hash| -hash[:average] }.first(number_of_examples)
+      end
+    end
+
+    # The `DeprecationNotification` is issued by the reporter when a deprecated
+    # part of RSpec is encountered. It represents information about the
+    # deprecated call site.
+    #
+    # @attr message [String] A custom message about the deprecation
+    # @attr deprecated [String] A custom message about the deprecation (alias of
+    #   message)
+    # @attr replacement [String] An optional replacement for the deprecation
+    # @attr call_site [String] An optional call site from which the deprecation
+    #   was issued
+    DeprecationNotification = Struct.new(:deprecated, :message, :replacement, :call_site)
+    class DeprecationNotification
+      private_class_method :new
+
+      # @api
+      # Convenience way to initialize the notification
+      def self.from_hash(data)
+        new data[:deprecated], data[:message], data[:replacement], data[:call_site]
+      end
+    end
+
+    # `NullNotification` represents a placeholder value for notifications that
+    # currently require no information, but we may wish to extend in future.
+    class NullNotification
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/option_parser.rb b/rspec-core/lib/rspec/core/option_parser.rb
new file mode 100644
index 0000000..8ee1716
--- /dev/null
+++ b/rspec-core/lib/rspec/core/option_parser.rb
@@ -0,0 +1,228 @@
+# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html
+require 'optparse'
+
+module RSpec::Core
+  # @private
+  class Parser
+    def self.parse(args)
+      new.parse(args)
+    end
+
+    def parse(args)
+      return {} if args.empty?
+
+      options = args.delete('--tty') ? { :tty => true } : {}
+      begin
+        parser(options).parse!(args)
+      rescue OptionParser::InvalidOption => e
+        abort "#{e.message}\n\nPlease use --help for a listing of valid options"
+      end
+
+      options
+    end
+
+    def parser(options)
+      OptionParser.new do |parser|
+        parser.banner = "Usage: rspec [options] [files or directories]\n\n"
+
+        parser.on('-I PATH', 'Specify PATH to add to $LOAD_PATH (may be used more than once).') do |dirs|
+          options[:libs] ||= []
+          options[:libs].concat(dirs.split(File::PATH_SEPARATOR))
+        end
+
+        parser.on('-r', '--require PATH', 'Require a file.') do |path|
+          options[:requires] ||= []
+          options[:requires] << path
+        end
+
+        parser.on('-O', '--options PATH', 'Specify the path to a custom options file.') do |path|
+          options[:custom_options_file] = path
+        end
+
+        parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.',
+                  '  [defined] examples and groups are run in the order they are defined',
+                  '  [rand]    randomize the order of groups and examples',
+                  '  [random]  alias for rand',
+                  '  [random:SEED] e.g. --order random:123') do |o|
+          options[:order] = o
+        end
+
+        parser.on('--seed SEED', Integer, 'Equivalent of --order rand:SEED.') do |seed|
+          options[:order] = "rand:#{seed}"
+        end
+
+        parser.on('--fail-fast', 'Abort the run on first failure.') do |_o|
+          options[:fail_fast] = true
+        end
+
+        parser.on('--no-fail-fast', 'Do not abort the run on first failure.') do |_o|
+          options[:fail_fast] = false
+        end
+
+        parser.on('--failure-exit-code CODE', Integer,
+                  'Override the exit code used when there are failing specs.') do |code|
+          options[:failure_exit_code] = code
+        end
+
+        parser.on('--dry-run', 'Print the formatter output of your suite without',
+                  '  running any examples or hooks') do |_o|
+          options[:dry_run] = true
+        end
+
+        parser.on('-X', '--[no-]drb', 'Run examples via DRb.') do |o|
+          options[:drb] = o
+        end
+
+        parser.on('--drb-port PORT', 'Port to connect to the DRb server.') do |o|
+          options[:drb_port] = o.to_i
+        end
+
+        parser.on('--init', 'Initialize your project with RSpec.') do |_cmd|
+          RSpec::Support.require_rspec_core "project_initializer"
+          ProjectInitializer.new.run
+          exit
+        end
+
+        parser.separator("\n  **** Output ****\n\n")
+
+        parser.on('-f', '--format FORMATTER', 'Choose a formatter.',
+                  '  [p]rogress (default - dots)',
+                  '  [d]ocumentation (group and example names)',
+                  '  [h]tml',
+                  '  [j]son',
+                  '  custom formatter class name') do |o|
+          options[:formatters] ||= []
+          options[:formatters] << [o]
+        end
+
+        parser.on('-o', '--out FILE',
+                  'Write output to a file instead of $stdout. This option applies',
+                  '  to the previously specified --format, or the default format',
+                  '  if no format is specified.'
+                 ) do |o|
+          options[:formatters] ||= [['progress']]
+          options[:formatters].last << o
+        end
+
+        parser.on('--deprecation-out FILE', 'Write deprecation warnings to a file instead of $stderr.') do |file|
+          options[:deprecation_stream] = file
+        end
+
+        parser.on('-b', '--backtrace', 'Enable full backtrace.') do |_o|
+          options[:full_backtrace] = true
+        end
+
+        parser.on('-c', '--[no-]color', '--[no-]colour', 'Enable color in the output.') do |o|
+          options[:color] = o
+        end
+
+        parser.on('-p', '--[no-]profile [COUNT]',
+                  'Enable profiling of examples and list the slowest examples (default: 10).') do |argument|
+          options[:profile_examples] = if argument.nil?
+                                         true
+                                       elsif argument == false
+                                         false
+                                       else
+                                         begin
+                                           Integer(argument)
+                                         rescue ArgumentError
+                                           RSpec.warning "Non integer specified as profile count, seperate " \
+                                                       "your path from options with -- e.g. " \
+                                                       "`rspec --profile -- #{argument}`",
+                                                         :call_site => nil
+                                           true
+                                         end
+                                       end
+        end
+
+        parser.on('-w', '--warnings', 'Enable ruby warnings') do
+          $VERBOSE = true
+        end
+
+        parser.separator <<-FILTERING
+
+  **** Filtering/tags ****
+
+    In addition to the following options for selecting specific files, groups,
+    or examples, you can select a single example by appending the line number to
+    the filename:
+
+      rspec path/to/a_spec.rb:37
+
+FILTERING
+
+        parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb").') do |o|
+          options[:pattern] = o
+        end
+
+        parser.on('--exclude-pattern PATTERN',
+                  'Load files except those matching pattern. Opposite effect of --pattern.') do |o|
+          options[:exclude_pattern] = o
+        end
+
+        parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be",
+                  "  used more than once)") do |o|
+          (options[:full_description] ||= []) << Regexp.compile(Regexp.escape(o))
+        end
+
+        parser.on('-t', '--tag TAG[:VALUE]',
+                  'Run examples with the specified tag, or exclude examples',
+                  'by adding ~ before the tag.',
+                  '  - e.g. ~slow',
+                  '  - TAG is always converted to a symbol') do |tag|
+          filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter
+
+          name, value = tag.gsub(/^(~@|~|@)/, '').split(':', 2)
+          name = name.to_sym
+
+          options[filter_type] ||= {}
+          options[filter_type][name] = case value
+                                       when  nil        then true # The default value for tags is true
+                                       when 'true'      then true
+                                       when 'false'     then false
+                                       when 'nil'       then nil
+                                       when /^:/        then value[1..-1].to_sym
+                                       when /^\d+$/     then Integer(value)
+                                       when /^\d+.\d+$/ then Float(value)
+                                       else
+                                         value
+                                       end
+        end
+
+        parser.on('--default-path PATH', 'Set the default path where RSpec looks for examples (can',
+                  '  be a path to a file or a directory).') do |path|
+          options[:default_path] = path
+        end
+
+        parser.separator("\n  **** Utility ****\n\n")
+
+        parser.on('-v', '--version', 'Display the version.') do
+          puts RSpec::Core::Version::STRING
+          exit
+        end
+
+        # These options would otherwise be confusing to users, so we forcibly
+        # prevent them from executing.
+        #
+        #   * --I is too similar to -I.
+        #   * -d was a shorthand for --debugger, which is removed, but now would
+        #     trigger --default-path.
+        invalid_options = %w[-d --I]
+
+        parser.on_tail('-h', '--help', "You're looking at it.") do
+          # Removing the blank invalid options from the output.
+          puts parser.to_s.gsub(/^\s+(#{invalid_options.join('|')})\s*$\n/, '')
+          exit
+        end
+
+        # This prevents usage of the invalid_options.
+        invalid_options.each do |option|
+          parser.on(option) do
+            raise OptionParser::InvalidOption.new
+          end
+        end
+
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/ordering.rb b/rspec-core/lib/rspec/core/ordering.rb
new file mode 100644
index 0000000..c274cdc
--- /dev/null
+++ b/rspec-core/lib/rspec/core/ordering.rb
@@ -0,0 +1,155 @@
+module RSpec
+  module Core
+    if defined?(::Random)
+      # @private
+      RandomNumberGenerator = ::Random
+    else
+      RSpec::Support.require_rspec_core "backport_random"
+      # @private
+      RandomNumberGenerator = RSpec::Core::Backports::Random
+    end
+
+    # @private
+    module Ordering
+      # @private
+      # The default global ordering (defined order).
+      class Identity
+        def order(items)
+          items
+        end
+      end
+
+      # @private
+      # Orders items randomly.
+      class Random
+        def initialize(configuration)
+          @configuration = configuration
+          @used = false
+        end
+
+        def used?
+          @used
+        end
+
+        def order(items)
+          @used = true
+          rng = RandomNumberGenerator.new(@configuration.seed)
+          shuffle items, rng
+        end
+
+        if RUBY_VERSION > '1.9.3'
+          def shuffle(list, rng)
+            list.shuffle(:random => rng)
+          end
+        else
+          def shuffle(list, rng)
+            shuffled = list.dup
+            shuffled.size.times do |i|
+              j = i + rng.rand(shuffled.size - i)
+              next if i == j
+              shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
+            end
+
+            shuffled
+          end
+        end
+      end
+
+      # @private
+      # Orders items based on a custom block.
+      class Custom
+        def initialize(callable)
+          @callable = callable
+        end
+
+        def order(list)
+          @callable.call(list)
+        end
+      end
+
+      # @private
+      # Stores the different ordering strategies.
+      class Registry
+        def initialize(configuration)
+          @configuration = configuration
+          @strategies    = {}
+
+          register(:random,  Random.new(configuration))
+
+          identity = Identity.new
+          register(:defined, identity)
+
+          # The default global ordering is --defined.
+          register(:global, identity)
+        end
+
+        def fetch(name, &fallback)
+          @strategies.fetch(name, &fallback)
+        end
+
+        def register(sym, strategy)
+          @strategies[sym] = strategy
+        end
+
+        def used_random_seed?
+          @strategies[:random].used?
+        end
+      end
+
+      # @private
+      # Manages ordering configuration.
+      #
+      # @note This is not intended to be used externally. Use
+      #       the APIs provided by `RSpec::Core::Configuration` instead.
+      class ConfigurationManager
+        attr_reader :seed, :ordering_registry
+
+        def initialize
+          @ordering_registry = Registry.new(self)
+          @seed = rand(0xFFFF)
+          @seed_forced = false
+          @order_forced = false
+        end
+
+        def seed_used?
+          ordering_registry.used_random_seed?
+        end
+
+        def seed=(seed)
+          return if @seed_forced
+          register_ordering(:global, ordering_registry.fetch(:random))
+          @seed = seed.to_i
+        end
+
+        def order=(type)
+          order, seed = type.to_s.split(':')
+          @seed = seed.to_i if seed
+
+          ordering_name = if order.include?('rand')
+                            :random
+                          elsif order == 'defined'
+                            :defined
+                          end
+
+          register_ordering(:global, ordering_registry.fetch(ordering_name)) if ordering_name
+        end
+
+        def force(hash)
+          if hash.key?(:seed)
+            self.seed = hash[:seed]
+            @seed_forced  = true
+            @order_forced = true
+          elsif hash.key?(:order)
+            self.order = hash[:order]
+            @order_forced = true
+          end
+        end
+
+        def register_ordering(name, strategy=Custom.new(Proc.new { |l| yield l }))
+          return if @order_forced && name == :global
+          ordering_registry.register(name, strategy)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/pending.rb b/rspec-core/lib/rspec/core/pending.rb
new file mode 100644
index 0000000..f04e3be
--- /dev/null
+++ b/rspec-core/lib/rspec/core/pending.rb
@@ -0,0 +1,165 @@
+module RSpec
+  module Core
+    # Provides methods to mark examples as pending. These methods are available
+    # to be called from within any example or hook.
+    module Pending
+      # Raised in the middle of an example to indicate that it should be marked
+      # as skipped.
+      class SkipDeclaredInExample < StandardError
+        attr_reader :argument
+
+        def initialize(argument)
+          @argument = argument
+        end
+      end
+
+      # If Test::Unit is loaded, we'll use its error as baseclass, so that
+      # Test::Unit will report unmet RSpec expectations as failures rather than
+      # errors.
+      begin
+        class PendingExampleFixedError < Test::Unit::AssertionFailedError; end
+      rescue
+        class PendingExampleFixedError < StandardError; end
+      end
+
+      # @private
+      NO_REASON_GIVEN = 'No reason given'
+
+      # @private
+      NOT_YET_IMPLEMENTED = 'Not yet implemented'
+
+      # @overload pending()
+      # @overload pending(message)
+      #
+      # Marks an example as pending. The rest of the example will still be
+      # executed, and if it passes the example will fail to indicate that the
+      # pending can be removed.
+      #
+      # @param message [String] optional message to add to the summary report.
+      #
+      # @example
+      #     describe "an example" do
+      #       # reported as "Pending: no reason given"
+      #       it "is pending with no message" do
+      #         pending
+      #         raise "broken"
+      #       end
+      #
+      #       # reported as "Pending: something else getting finished"
+      #       it "is pending with a custom message" do
+      #         pending("something else getting finished")
+      #         raise "broken"
+      #       end
+      #     end
+      #
+      # @note `before(:example)` hooks are eval'd when you use the `pending`
+      #   method within an example. If you want to declare an example `pending`
+      #   and bypass the `before` hooks as well, you can pass `:pending => true`
+      #   to the `it` method:
+      #
+      #       it "does something", :pending => true do
+      #         # ...
+      #       end
+      #
+      #   or pass `:pending => "something else getting finished"` to add a
+      #   message to the summary report:
+      #
+      #       it "does something", :pending => "something else getting finished" do
+      #         # ...
+      #       end
+      def pending(message=nil)
+        current_example = RSpec.current_example
+
+        if block_given?
+          raise ArgumentError, <<-EOS.gsub(/^\s+\|/, '')
+            |The semantics of `RSpec::Core::Pending#pending` have changed in
+            |RSpec 3. In RSpec 2.x, it caused the example to be skipped. In
+            |RSpec 3, the rest of the example is still run but is expected to
+            |fail, and will be marked as a failure (rather than as pending) if
+            |the example passes.
+            |
+            |Passing a block within an example is now deprecated. Marking the
+            |example as pending provides the same behavior in RSpec 3 which was
+            |provided only by the block in RSpec 2.x.
+            |
+            |Move the code in the block provided to `pending` into the rest of
+            |the example body.
+            |
+            |Called from #{CallerFilter.first_non_rspec_line}.
+            |
+          EOS
+        elsif current_example
+          Pending.mark_pending! current_example, message
+        else
+          raise "`pending` may not be used outside of examples, such as in " \
+                "before(:context). Maybe you want `skip`?"
+        end
+      end
+
+      # @overload skip()
+      # @overload skip(message)
+      #
+      # Marks an example as pending and skips execution.
+      #
+      # @param message [String] optional message to add to the summary report.
+      #
+      # @example
+      #     describe "an example" do
+      #       # reported as "Pending: no reason given"
+      #       it "is skipped with no message" do
+      #         skip
+      #       end
+      #
+      #       # reported as "Pending: something else getting finished"
+      #       it "is skipped with a custom message" do
+      #         skip "something else getting finished"
+      #       end
+      #     end
+      def skip(message=nil)
+        current_example = RSpec.current_example
+
+        Pending.mark_skipped!(current_example, message) if current_example
+
+        raise SkipDeclaredInExample.new(message)
+      end
+
+      # @private
+      #
+      # Mark example as skipped.
+      #
+      # @param example [RSpec::Core::Example] the example to mark as skipped
+      # @param message_or_bool [Boolean, String] the message to use, or true
+      def self.mark_skipped!(example, message_or_bool)
+        Pending.mark_pending! example, message_or_bool
+        example.metadata[:skip] = true
+      end
+
+      # @private
+      #
+      # Mark example as pending.
+      #
+      # @param example [RSpec::Core::Example] the example to mark as pending
+      # @param message_or_bool [Boolean, String] the message to use, or true
+      def self.mark_pending!(example, message_or_bool)
+        message = if !message_or_bool || !(String === message_or_bool)
+                    NO_REASON_GIVEN
+                  else
+                    message_or_bool
+                  end
+
+        example.metadata[:pending] = true
+        example.execution_result.pending_message = message
+        example.execution_result.pending_fixed = false
+      end
+
+      # @private
+      #
+      # Mark example as fixed.
+      #
+      # @param example [RSpec::Core::Example] the example to mark as fixed
+      def self.mark_fixed!(example)
+        example.execution_result.pending_fixed = true
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/project_initializer.rb b/rspec-core/lib/rspec/core/project_initializer.rb
new file mode 100644
index 0000000..ca707e0
--- /dev/null
+++ b/rspec-core/lib/rspec/core/project_initializer.rb
@@ -0,0 +1,48 @@
+RSpec::Support.require_rspec_support "directory_maker"
+
+module RSpec
+  module Core
+    # @private
+    # Generates conventional files for an RSpec project.
+    class ProjectInitializer
+      attr_reader :destination, :stream, :template_path
+
+      DOT_RSPEC_FILE = '.rspec'
+      SPEC_HELPER_FILE =  'spec/spec_helper.rb'
+
+      def initialize(opts={})
+        @destination = opts.fetch(:destination, Dir.getwd)
+        @stream = opts.fetch(:report_stream, $stdout)
+        @template_path = opts.fetch(:template_path) do
+          File.expand_path("../project_initializer", __FILE__)
+        end
+      end
+
+      def run
+        copy_template DOT_RSPEC_FILE
+        copy_template SPEC_HELPER_FILE
+      end
+
+    private
+
+      def copy_template(file)
+        destination_file = File.join(destination, file)
+        return report_exists(file) if File.exist?(destination_file)
+
+        report_creating(file)
+        RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(destination_file))
+        File.open(destination_file, 'w') do |f|
+          f.write File.read(File.join(template_path, file))
+        end
+      end
+
+      def report_exists(file)
+        stream.puts "   exist   #{file}"
+      end
+
+      def report_creating(file)
+        stream.puts "  create   #{file}"
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/project_initializer/.rspec b/rspec-core/lib/rspec/core/project_initializer/.rspec
new file mode 100644
index 0000000..83e16f8
--- /dev/null
+++ b/rspec-core/lib/rspec/core/project_initializer/.rspec
@@ -0,0 +1,2 @@
+--color
+--require spec_helper
diff --git a/rspec-core/lib/rspec/core/project_initializer/spec/spec_helper.rb b/rspec-core/lib/rspec/core/project_initializer/spec/spec_helper.rb
new file mode 100644
index 0000000..b598abe
--- /dev/null
+++ b/rspec-core/lib/rspec/core/project_initializer/spec/spec_helper.rb
@@ -0,0 +1,91 @@
+# This file was generated by the `rspec --init` command. Conventionally, all
+# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
+# The generated `.rspec` file contains `--require spec_helper` which will cause
+# this file to always be loaded, without a need to explicitly require it in any
+# files.
+#
+# Given that it is always loaded, you are encouraged to keep this file as
+# light-weight as possible. Requiring heavyweight dependencies from this file
+# will add to the boot time of your test suite on EVERY test run, even for an
+# individual file that may not need all of that loaded. Instead, consider making
+# a separate helper file that requires the additional dependencies and performs
+# the additional setup, and require it from the spec files that actually need
+# it.
+#
+# The `.rspec` file also contains a few flags that are not defaults but that
+# users commonly want.
+#
+# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+RSpec.configure do |config|
+  # rspec-expectations config goes here. You can use an alternate
+  # assertion/expectation library such as wrong or the stdlib/minitest
+  # assertions if you prefer.
+  config.expect_with :rspec do |expectations|
+    # This option will default to `true` in RSpec 4. It makes the `description`
+    # and `failure_message` of custom matchers include text for helper methods
+    # defined using `chain`, e.g.:
+    #     be_bigger_than(2).and_smaller_than(4).description
+    #     # => "be bigger than 2 and smaller than 4"
+    # ...rather than:
+    #     # => "be bigger than 2"
+    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+  end
+
+  # rspec-mocks config goes here. You can use an alternate test double
+  # library (such as bogus or mocha) by changing the `mock_with` option here.
+  config.mock_with :rspec do |mocks|
+    # Prevents you from mocking or stubbing a method that does not exist on
+    # a real object. This is generally recommended, and will default to
+    # `true` in RSpec 4.
+    mocks.verify_partial_doubles = true
+  end
+
+# The settings below are suggested to provide a good initial experience
+# with RSpec, but feel free to customize to your heart's content.
+=begin
+  # These two settings work together to allow you to limit a spec run
+  # to individual examples or groups you care about by tagging them with
+  # `:focus` metadata. When nothing is tagged with `:focus`, all examples
+  # get run.
+  config.filter_run :focus
+  config.run_all_when_everything_filtered = true
+
+  # Limits the available syntax to the non-monkey patched syntax that is
+  # recommended. For more details, see:
+  #   - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
+  #   - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
+  #   - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
+  config.disable_monkey_patching!
+
+  # This setting enables warnings. It's recommended, but in some cases may
+  # be too noisy due to issues in dependencies.
+  config.warnings = true
+
+  # Many RSpec users commonly either run the entire suite or an individual
+  # file, and it's useful to allow more verbose output when running an
+  # individual spec file.
+  if config.files_to_run.one?
+    # Use the documentation formatter for detailed output,
+    # unless a formatter has already been configured
+    # (e.g. via a command-line flag).
+    config.default_formatter = 'doc'
+  end
+
+  # Print the 10 slowest examples and example groups at the
+  # end of the spec run, to help surface which specs are running
+  # particularly slow.
+  config.profile_examples = 10
+
+  # Run specs in random order to surface order dependencies. If you find an
+  # order dependency and want to debug it, you can fix the order by providing
+  # the seed, which is printed after each run.
+  #     --seed 1234
+  config.order = :random
+
+  # Seed global randomization in this process using the `--seed` CLI option.
+  # Setting this allows you to use `--seed` to deterministically reproduce
+  # test failures related to randomization by passing the same `--seed` value
+  # as the one that triggered the failure.
+  Kernel.srand config.seed
+=end
+end
diff --git a/rspec-core/lib/rspec/core/rake_task.rb b/rspec-core/lib/rspec/core/rake_task.rb
new file mode 100644
index 0000000..baf1c44
--- /dev/null
+++ b/rspec-core/lib/rspec/core/rake_task.rb
@@ -0,0 +1,172 @@
+require 'rake'
+require 'rake/tasklib'
+require 'rspec/support/ruby_features'
+
+module RSpec
+  module Core
+    # RSpec rake task
+    #
+    # @see Rakefile
+    class RakeTask < ::Rake::TaskLib
+      include ::Rake::DSL if defined?(::Rake::DSL)
+
+      # Default path to the RSpec executable.
+      DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__)
+
+      # Default pattern for spec files.
+      DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
+
+      # Name of task. Defaults to `:spec`.
+      attr_accessor :name
+
+      # Files matching this pattern will be loaded.
+      # Defaults to `'spec/**{,/*/**}/*_spec.rb'`.
+      attr_accessor :pattern
+
+      # Files matching this pattern will be excluded.
+      # Defaults to `nil`.
+      attr_accessor :exclude_pattern
+
+      # Whether or not to fail Rake when an error occurs (typically when
+      # examples fail). Defaults to `true`.
+      attr_accessor :fail_on_error
+
+      # A message to print to stderr when there are failures.
+      attr_accessor :failure_message
+
+      # Use verbose output. If this is set to true, the task will print the
+      # executed spec command to stdout. Defaults to `true`.
+      attr_accessor :verbose
+
+      # Command line options to pass to ruby. Defaults to `nil`.
+      attr_accessor :ruby_opts
+
+      # Path to RSpec. Defaults to the absolute path to the
+      # rspec binary from the loaded rspec-core gem.
+      attr_accessor :rspec_path
+
+      # Command line options to pass to RSpec. Defaults to `nil`.
+      attr_accessor :rspec_opts
+
+      def initialize(*args, &task_block)
+        @name          = args.shift || :spec
+        @ruby_opts     = nil
+        @rspec_opts    = nil
+        @verbose       = true
+        @fail_on_error = true
+        @rspec_path    = DEFAULT_RSPEC_PATH
+        @pattern       = DEFAULT_PATTERN
+
+        define(args, &task_block)
+      end
+
+      # @private
+      def run_task(verbose)
+        command = spec_command
+
+        begin
+          puts command if verbose
+          success = system(command)
+        rescue
+          puts failure_message if failure_message
+        end
+
+        return unless fail_on_error && !success
+
+        $stderr.puts "#{command} failed" if verbose
+        exit $?.exitstatus
+      end
+
+    private
+
+      # @private
+      def define(args, &task_block)
+        desc "Run RSpec code examples" unless ::Rake.application.last_comment
+
+        task name, *args do |_, task_args|
+          RakeFileUtils.__send__(:verbose, verbose) do
+            task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block
+            run_task verbose
+          end
+        end
+      end
+
+      def file_inclusion_specification
+        if ENV['SPEC']
+          FileList[ ENV['SPEC']].sort
+        elsif String === pattern && !File.exist?(pattern)
+          "--pattern #{escape pattern}"
+        else
+          # Before RSpec 3.1, we used `FileList` to get the list of matched
+          # files, and then pass that along to the `rspec` command. Starting
+          # with 3.1, we prefer to pass along the pattern as-is to the `rspec`
+          # command, for 3 reasons:
+          #
+          #   * It's *much* less verbose to pass one `--pattern` option than a
+          #     long list of files.
+          #   * It ensures `task.pattern` and `--pattern` have the same
+          #     behavior.
+          #   * It fixes a bug, where
+          #     `task.pattern = pattern_that_matches_no_files` would run *all*
+          #     files because it would cause no pattern or file args to get
+          #     passed to `rspec`, which causes all files to get run.
+          #
+          # However, `FileList` is *far* more flexible than the `--pattern`
+          # option. Specifically, it supports individual files and directories,
+          # as well as arrays of files, directories and globs, as well as other
+          # `FileList` objects.
+          #
+          # For backwards compatibility, we have to fall back to using FileList
+          # if the user has passed a `pattern` option that will not work with
+          # `--pattern`.
+          #
+          # TODO: consider deprecating support for this and removing it in
+          #   RSpec 4.
+          FileList[pattern].sort.map { |file| escape file }
+        end
+      end
+
+      if RSpec::Support::OS.windows?
+        def escape(shell_command)
+          "'#{shell_command.gsub("'", "\'")}'"
+        end
+      else
+        require 'shellwords'
+
+        def escape(shell_command)
+          shell_command.shellescape
+        end
+      end
+
+      def file_exclusion_specification
+        " --exclude-pattern #{escape exclude_pattern}" if exclude_pattern
+      end
+
+      def spec_command
+        cmd_parts = []
+        cmd_parts << RUBY
+        cmd_parts << ruby_opts
+        cmd_parts << rspec_load_path
+        cmd_parts << escape(rspec_path)
+        cmd_parts << file_inclusion_specification
+        cmd_parts << file_exclusion_specification
+        cmd_parts << rspec_opts
+        cmd_parts.flatten.reject(&blank).join(" ")
+      end
+
+      def blank
+        lambda { |s| s.nil? || s == "" }
+      end
+
+      def rspec_load_path
+        @rspec_load_path ||= begin
+          core_and_support = $LOAD_PATH.grep(
+            /#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/
+          ).uniq
+
+          "-I#{core_and_support.map { |file| escape file }.join(File::PATH_SEPARATOR)}"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/reporter.rb b/rspec-core/lib/rspec/core/reporter.rb
new file mode 100644
index 0000000..912af50
--- /dev/null
+++ b/rspec-core/lib/rspec/core/reporter.rb
@@ -0,0 +1,172 @@
+module RSpec::Core
+  # A reporter will send notifications to listeners, usually formatters for the
+  # spec suite run.
+  class Reporter
+    def initialize(configuration)
+      @configuration = configuration
+      @listeners = Hash.new { |h, k| h[k] = Set.new }
+      @examples = []
+      @failed_examples = []
+      @pending_examples = []
+      @duration = @start = @load_time = nil
+    end
+
+    # @private
+    attr_reader :examples, :failed_examples, :pending_examples
+
+    # @private
+    def reset
+      @examples = []
+      @failed_examples = []
+      @pending_examples = []
+    end
+
+    # Registers a listener to a list of notifications. The reporter will send
+    # notification of events to all registered listeners.
+    #
+    # @param listener [Object] An obect that wishes to be notified of reporter
+    #   events
+    # @param notifications [Array] Array of symbols represents the events a
+    #   listener wishes to subscribe too
+    def register_listener(listener, *notifications)
+      notifications.each do |notification|
+        @listeners[notification.to_sym] << listener
+      end
+      true
+    end
+
+    # @private
+    def registered_listeners(notification)
+      @listeners[notification].to_a
+    end
+
+    # @api
+    # @overload report(count, &block)
+    # @overload report(count, &block)
+    # @param expected_example_count [Integer] the number of examples being run
+    # @yield [Block] block yields itself for further reporting.
+    #
+    # Initializes the report run and yields itself for further reporting. The
+    # block is required, so that the reporter can manage cleaning up after the
+    # run.
+    #
+    # @example
+    #
+    #     reporter.report(group.examples.size) do |r|
+    #       example_groups.map {|g| g.run(r) }
+    #     end
+    #
+    def report(expected_example_count)
+      start(expected_example_count)
+      begin
+        yield self
+      ensure
+        finish
+      end
+    end
+
+    # @private
+    def start(expected_example_count, time=RSpec::Core::Time.now)
+      @start = time
+      @load_time = (@start - @configuration.start_time).to_f
+      notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?)
+      notify :start, Notifications::StartNotification.new(expected_example_count, @load_time)
+    end
+
+    # @private
+    def message(message)
+      notify :message, Notifications::MessageNotification.new(message)
+    end
+
+    # @private
+    def example_group_started(group)
+      notify :example_group_started, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty?
+    end
+
+    # @private
+    def example_group_finished(group)
+      notify :example_group_finished, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty?
+    end
+
+    # @private
+    def example_started(example)
+      @examples << example
+      notify :example_started, Notifications::ExampleNotification.for(example)
+    end
+
+    # @private
+    def example_passed(example)
+      notify :example_passed, Notifications::ExampleNotification.for(example)
+    end
+
+    # @private
+    def example_failed(example)
+      @failed_examples << example
+      notify :example_failed, Notifications::ExampleNotification.for(example)
+    end
+
+    # @private
+    def example_pending(example)
+      @pending_examples << example
+      notify :example_pending, Notifications::ExampleNotification.for(example)
+    end
+
+    # @private
+    def deprecation(hash)
+      notify :deprecation, Notifications::DeprecationNotification.from_hash(hash)
+    end
+
+    # @private
+    def finish
+      stop
+      notify :start_dump,    Notifications::NullNotification
+      notify :dump_pending,  Notifications::ExamplesNotification.new(self)
+      notify :dump_failures, Notifications::ExamplesNotification.new(self)
+      notify :deprecation_summary, Notifications::NullNotification
+      unless mute_profile_output?
+        notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples,
+                                                                     @configuration.profile_examples)
+      end
+      notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples,
+                                                                   @pending_examples, @load_time)
+      notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?)
+    ensure
+      notify :close, Notifications::NullNotification
+    end
+
+    # @private
+    def stop
+      @duration = (RSpec::Core::Time.now - @start).to_f if @start
+      notify :stop, Notifications::ExamplesNotification.new(self)
+    end
+
+    # @private
+    def notify(event, notification)
+      registered_listeners(event).each do |formatter|
+        formatter.__send__(event, notification)
+      end
+    end
+
+  private
+
+    def mute_profile_output?
+      # Don't print out profiled info if there are failures and `--fail-fast` is
+      # used, it just clutters the output.
+      !@configuration.profile_examples? || (@configuration.fail_fast? && @failed_examples.size > 0)
+    end
+
+    def seed_used?
+      @configuration.seed && @configuration.seed_used?
+    end
+  end
+
+  # @private
+  # # Used in place of a {Reporter} for situations where we don't want reporting output.
+  class NullReporter
+  private
+
+    def method_missing(*)
+      # ignore
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/ruby_project.rb b/rspec-core/lib/rspec/core/ruby_project.rb
new file mode 100644
index 0000000..10c89f9
--- /dev/null
+++ b/rspec-core/lib/rspec/core/ruby_project.rb
@@ -0,0 +1,53 @@
+# This is borrowed (slightly modified) from Scott Taylor's
+# project_path project:
+#   http://github.com/smtlaissezfaire/project_path
+module RSpec
+  module Core
+    # @private
+    module RubyProject
+      def add_to_load_path(*dirs)
+        dirs.map { |dir| add_dir_to_load_path(File.join(root, dir)) }
+      end
+
+      def add_dir_to_load_path(dir)
+        $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir)
+      end
+
+      def root
+        @project_root ||= determine_root
+      end
+
+      def determine_root
+        find_first_parent_containing('spec') || '.'
+      end
+
+      def find_first_parent_containing(dir)
+        ascend_until { |path| File.exist?(File.join(path, dir)) }
+      end
+
+      def ascend_until
+        fs = File::SEPARATOR
+        escaped_slash = "\\#{fs}"
+        special = "_RSPEC_ESCAPED_SLASH_"
+        project_path = File.expand_path(".")
+        parts = project_path.gsub(escaped_slash, special).squeeze(fs).split(fs).map do |x|
+          x.gsub(special, escaped_slash)
+        end
+
+        until parts.empty?
+          path = parts.join(fs)
+          path = fs if path == ""
+          return path if yield(path)
+          parts.pop
+        end
+      end
+
+      module_function :add_to_load_path
+      module_function :add_dir_to_load_path
+      module_function :root
+      module_function :determine_root
+      module_function :find_first_parent_containing
+      module_function :ascend_until
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/runner.rb b/rspec-core/lib/rspec/core/runner.rb
new file mode 100644
index 0000000..af5612b
--- /dev/null
+++ b/rspec-core/lib/rspec/core/runner.rb
@@ -0,0 +1,155 @@
+module RSpec
+  module Core
+    # Provides the main entry point to run a suite of RSpec examples.
+    class Runner
+      # Register an `at_exit` hook that runs the suite when the process exits.
+      #
+      # @note This is not generally needed. The `rspec` command takes care
+      #       of running examples for you without involving an `at_exit`
+      #       hook. This is only needed if you are running specs using
+      #       the `ruby` command, and even then, the normal way to invoke
+      #       this is by requiring `rspec/autorun`.
+      def self.autorun
+        if autorun_disabled?
+          RSpec.deprecate("Requiring `rspec/autorun` when running RSpec via the `rspec` command")
+          return
+        elsif installed_at_exit? || running_in_drb?
+          return
+        end
+
+        at_exit do
+          # Don't bother running any specs and just let the program terminate
+          # if we got here due to an unrescued exception (anything other than
+          # SystemExit, which is raised when somebody calls Kernel#exit).
+          next unless $!.nil? || $!.is_a?(SystemExit)
+
+          # We got here because either the end of the program was reached or
+          # somebody called Kernel#exit. Run the specs and then override any
+          # existing exit status with RSpec's exit status if any specs failed.
+          invoke
+        end
+        @installed_at_exit = true
+      end
+
+      # Runs the suite of specs and exits the process with an appropriate exit
+      # code.
+      def self.invoke
+        disable_autorun!
+        status = run(ARGV, $stderr, $stdout).to_i
+        exit(status) if status != 0
+      end
+
+      # Run a suite of RSpec examples. Does not exit.
+      #
+      # This is used internally by RSpec to run a suite, but is available
+      # for use by any other automation tool.
+      #
+      # If you want to run this multiple times in the same process, and you
+      # want files like `spec_helper.rb` to be reloaded, be sure to load `load`
+      # instead of `require`.
+      #
+      # @param args [Array] command-line-supported arguments
+      # @param err [IO] error stream
+      # @param out [IO] output stream
+      # @return [Fixnum] exit status code. 0 if all specs passed,
+      #   or the configured failure exit code (1 by default) if specs
+      #   failed.
+      def self.run(args, err=$stderr, out=$stdout)
+        trap_interrupt
+        options = ConfigurationOptions.new(args)
+
+        if options.options[:drb]
+          require 'rspec/core/drb'
+          begin
+            DRbRunner.new(options).run(err, out)
+          rescue DRb::DRbConnError
+            err.puts "No DRb server is running. Running in local process instead ..."
+            new(options).run(err, out)
+          end
+        else
+          new(options).run(err, out)
+        end
+      end
+
+      def initialize(options, configuration=RSpec.configuration, world=RSpec.world)
+        @options       = options
+        @configuration = configuration
+        @world         = world
+      end
+
+      # Configures and runs a spec suite.
+      #
+      # @param err [IO] error stream
+      # @param out [IO] output stream
+      def run(err, out)
+        setup(err, out)
+        run_specs(@world.ordered_example_groups)
+      end
+
+      # Wires together the various configuration objects and state holders.
+      #
+      # @param err [IO] error stream
+      # @param out [IO] output stream
+      def setup(err, out)
+        @configuration.error_stream = err
+        @configuration.output_stream = out if @configuration.output_stream == $stdout
+        @options.configure(@configuration)
+        @configuration.load_spec_files
+        @world.announce_filters
+      end
+
+      # Runs the provided example groups.
+      #
+      # @param example_groups [Array<RSpec::Core::ExampleGroup>] groups to run
+      # @return [Fixnum] exit status code. 0 if all specs passed,
+      #   or the configured failure exit code (1 by default) if specs
+      #   failed.
+      def run_specs(example_groups)
+        @configuration.reporter.report(@world.example_count(example_groups)) do |reporter|
+          @configuration.with_suite_hooks do
+            example_groups.map { |g| g.run(reporter) }.all? ? 0 : @configuration.failure_exit_code
+          end
+        end
+      end
+
+      # @private
+      def self.disable_autorun!
+        @autorun_disabled = true
+      end
+
+      # @private
+      def self.autorun_disabled?
+        @autorun_disabled ||= false
+      end
+
+      # @private
+      def self.installed_at_exit?
+        @installed_at_exit ||= false
+      end
+
+      # @private
+      # rubocop:disable Lint/EnsureReturn
+      def self.running_in_drb?
+        if defined?(DRb) && DRb.current_server
+          require 'socket'
+          require 'uri'
+          local_ipv4 = IPSocket.getaddress(Socket.gethostname)
+          local_drb = ["127.0.0.1", "localhost", local_ipv4].any? { |addr| addr == URI(DRb.current_server.uri).host }
+        end
+      rescue DRb::DRbServerNotFound
+      ensure
+        return local_drb || false
+      end
+      # rubocop:enable Lint/EnsureReturn
+
+      # @private
+      def self.trap_interrupt
+        trap('INT') do
+          exit!(1) if RSpec.world.wants_to_quit
+          RSpec.world.wants_to_quit = true
+          STDERR.puts "\nRSpec is shutting down and will print the summary report... Interrupt again to force quit."
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/sandbox.rb b/rspec-core/lib/rspec/core/sandbox.rb
new file mode 100644
index 0000000..e7d518c
--- /dev/null
+++ b/rspec-core/lib/rspec/core/sandbox.rb
@@ -0,0 +1,37 @@
+module RSpec
+  module Core
+    # A sandbox isolates the enclosed code into an environment that looks 'new'
+    # meaning globally accessed objects are reset for the duration of the
+    # sandbox.
+    #
+    # @note This module is not normally available. You must require
+    #   `rspec/core/sandbox` to load it.
+    module Sandbox
+      # Execute a provided block with RSpec global objects (configuration,
+      # world) reset.  This is used to test RSpec with RSpec.
+      #
+      # When calling this the configuration is passed into the provided block.
+      # Use this to set custom configs for your sandboxed examples.
+      #
+      # ```
+      # Sandbox.sandboxed do |config|
+      #   config.before(:context) { RSpec.current_example = nil }
+      # end
+      # ```
+      def self.sandboxed
+        orig_config  = RSpec.configuration
+        orig_world   = RSpec.world
+        orig_example = RSpec.current_example
+
+        RSpec.configuration = RSpec::Core::Configuration.new
+        RSpec.world         = RSpec::Core::World.new(RSpec.configuration)
+
+        yield RSpec.configuration
+      ensure
+        RSpec.configuration   = orig_config
+        RSpec.world           = orig_world
+        RSpec.current_example = orig_example
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/shared_context.rb b/rspec-core/lib/rspec/core/shared_context.rb
new file mode 100644
index 0000000..6de7f64
--- /dev/null
+++ b/rspec-core/lib/rspec/core/shared_context.rb
@@ -0,0 +1,55 @@
+module RSpec
+  module Core
+    # Exposes {ExampleGroup}-level methods to a module, so you can include that
+    # module in an {ExampleGroup}.
+    #
+    # @example
+    #
+    #     module LoggedInAsAdmin
+    #       extend RSpec::Core::SharedContext
+    #       before(:example) do
+    #         log_in_as :admin
+    #       end
+    #     end
+    #
+    #     describe "admin section" do
+    #       include LoggedInAsAdmin
+    #       # ...
+    #     end
+    module SharedContext
+      # @private
+      def included(group)
+        __shared_context_recordings.each do |recording|
+          recording.playback_onto(group)
+        end
+      end
+
+      # @private
+      def __shared_context_recordings
+        @__shared_context_recordings ||= []
+      end
+
+      # @private
+      Recording = Struct.new(:method_name, :args, :block) do
+        def playback_onto(group)
+          group.__send__(method_name, *args, &block)
+        end
+      end
+
+      # @private
+      def self.record(methods)
+        methods.each do |meth|
+          define_method(meth) do |*args, &block|
+            __shared_context_recordings << Recording.new(meth, args, block)
+          end
+        end
+      end
+
+      # @private
+      record [:describe, :context] + Hooks.instance_methods(false) +
+        MemoizedHelpers::ClassMethods.instance_methods(false)
+    end
+  end
+  # @private
+  SharedContext = Core::SharedContext
+end
diff --git a/rspec-core/lib/rspec/core/shared_example_group.rb b/rspec-core/lib/rspec/core/shared_example_group.rb
new file mode 100644
index 0000000..4af3260
--- /dev/null
+++ b/rspec-core/lib/rspec/core/shared_example_group.rb
@@ -0,0 +1,208 @@
+module RSpec
+  module Core
+    # Represents some functionality that is shared with multiple example groups.
+    # The functionality is defined by the provided block, which is lazily
+    # eval'd when the `SharedExampleGroupModule` instance is included in an example
+    # group.
+    class SharedExampleGroupModule < Module
+      def initialize(description, definition)
+        @description = description
+        @definition  = definition
+      end
+
+      # Provides a human-readable representation of this module.
+      def inspect
+        "#<#{self.class.name} #{@description.inspect}>"
+      end
+      alias to_s inspect
+
+      # Ruby callback for when a module is included in another module is class.
+      # Our definition evaluates the shared group block in the context of the
+      # including example group.
+      def included(klass)
+        inclusion_line = klass.metadata[:location]
+        SharedExampleGroupInclusionStackFrame.with_frame(@description, inclusion_line) do
+          klass.class_exec(&@definition)
+        end
+      end
+    end
+
+    # Shared example groups let you define common context and/or common
+    # examples that you wish to use in multiple example groups.
+    #
+    # When defined, the shared group block is stored for later evaluation.
+    # It can later be included in an example group either explicitly
+    # (using `include_examples`, `include_context` or `it_behaves_like`)
+    # or implicitly (via matching metadata).
+    #
+    # Named shared example groups are scoped based on where they are
+    # defined. Shared groups defined in an example group are available
+    # for inclusion in that example group or any child example groups,
+    # but not in any parent or sibling example groups. Shared example
+    # groups defined at the top level can be included from any example group.
+    module SharedExampleGroup
+      # @overload shared_examples(name, &block)
+      #   @param name [String, Symbol, Module] identifer to use when looking up
+      #     this shared group
+      #   @param block The block to be eval'd
+      # @overload shared_examples(name, metadata, &block)
+      #   @param name [String, Symbol, Module] identifer to use when looking up
+      #     this shared group
+      #   @param metadata [Array<Symbol>, Hash] metadata to attach to this
+      #     group; any example group or example with matching metadata will
+      #     automatically include this shared example group.
+      #   @param block The block to be eval'd
+      # @overload shared_examples(metadata, &block)
+      #   @param metadata [Array<Symbol>, Hash] metadata to attach to this
+      #     group; any example group or example with matching metadata will
+      #     automatically include this shared example group.
+      #   @param block The block to be eval'd
+      #
+      # Stores the block for later use. The block will be evaluated
+      # in the context of an example group via `include_examples`,
+      # `include_context`, or `it_behaves_like`.
+      #
+      # @example
+      #   shared_examples "auditable" do
+      #     it "stores an audit record on save!" do
+      #       expect { auditable.save! }.to change(Audit, :count).by(1)
+      #     end
+      #   end
+      #
+      #   describe Account do
+      #     it_behaves_like "auditable" do
+      #       let(:auditable) { Account.new }
+      #     end
+      #   end
+      #
+      # @see ExampleGroup.it_behaves_like
+      # @see ExampleGroup.include_examples
+      # @see ExampleGroup.include_context
+      def shared_examples(name, *args, &block)
+        top_level = self == ExampleGroup
+        if top_level && RSpec.thread_local_metadata[:in_example_group]
+          raise "Creating isolated shared examples from within a context is " \
+                "not allowed. Remove `RSpec.` prefix or move this to a " \
+                "top-level scope."
+        end
+
+        RSpec.world.shared_example_group_registry.add(self, name, *args, &block)
+      end
+      alias shared_context      shared_examples
+      alias shared_examples_for shared_examples
+
+      # @api private
+      #
+      # Shared examples top level DSL.
+      module TopLevelDSL
+        # @private
+        def self.definitions
+          proc do
+            def shared_examples(name, *args, &block)
+              RSpec.world.shared_example_group_registry.add(:main, name, *args, &block)
+            end
+            alias shared_context      shared_examples
+            alias shared_examples_for shared_examples
+          end
+        end
+
+        # @private
+        def self.exposed_globally?
+          @exposed_globally ||= false
+        end
+
+        # @api private
+        #
+        # Adds the top level DSL methods to Module and the top level binding.
+        def self.expose_globally!
+          return if exposed_globally?
+          Core::DSL.change_global_dsl(&definitions)
+          @exposed_globally = true
+        end
+
+        # @api private
+        #
+        # Removes the top level DSL methods to Module and the top level binding.
+        def self.remove_globally!
+          return unless exposed_globally?
+
+          Core::DSL.change_global_dsl do
+            undef shared_examples
+            undef shared_context
+            undef shared_examples_for
+          end
+
+          @exposed_globally = false
+        end
+      end
+
+      # @private
+      class Registry
+        def add(context, name, *metadata_args, &block)
+          ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line }
+
+          if valid_name?(name)
+            warn_if_key_taken context, name, block
+            shared_example_groups[context][name] = block
+          else
+            metadata_args.unshift name
+          end
+
+          return if metadata_args.empty?
+          RSpec.configuration.include SharedExampleGroupModule.new(name, block), *metadata_args
+        end
+
+        def find(lookup_contexts, name)
+          lookup_contexts.each do |context|
+            found = shared_example_groups[context][name]
+            return found if found
+          end
+
+          shared_example_groups[:main][name]
+        end
+
+      private
+
+        def shared_example_groups
+          @shared_example_groups ||= Hash.new { |hash, context| hash[context] = {} }
+        end
+
+        def valid_name?(candidate)
+          case candidate
+          when String, Symbol, Module then true
+          else false
+          end
+        end
+
+        def warn_if_key_taken(context, key, new_block)
+          existing_block = shared_example_groups[context][key]
+
+          return unless existing_block
+
+          RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
+            |WARNING: Shared example group '#{key}' has been previously defined at:
+            |  #{formatted_location existing_block}
+            |...and you are now defining it at:
+            |  #{formatted_location new_block}
+            |The new definition will overwrite the original one.
+          WARNING
+        end
+
+        def formatted_location(block)
+          block.source_location.join ":"
+        end
+
+        if Proc.method_defined?(:source_location)
+          def ensure_block_has_source_location(_block); end
+        else # for 1.8.7
+          def ensure_block_has_source_location(block)
+            source_location = yield.split(':')
+            block.extend Module.new { define_method(:source_location) { source_location } }
+          end
+        end
+      end
+    end
+  end
+
+  instance_exec(&Core::SharedExampleGroup::TopLevelDSL.definitions)
+end
diff --git a/rspec-core/lib/rspec/core/test_unit_assertions_adapter.rb b/rspec-core/lib/rspec/core/test_unit_assertions_adapter.rb
new file mode 100644
index 0000000..d84ecb1
--- /dev/null
+++ b/rspec-core/lib/rspec/core/test_unit_assertions_adapter.rb
@@ -0,0 +1,30 @@
+require 'test/unit/assertions'
+
+module RSpec
+  module Core
+    # @private
+    module TestUnitAssertionsAdapter
+      include ::Test::Unit::Assertions
+
+      # If using test/unit from Ruby core with Ruby 1.9+, it includes
+      # MiniTest::Assertions by default. Note the upcasing of 'Test'.
+      #
+      # If the test/unit gem is being loaded, it will not include any minitest
+      # assertions.
+      #
+      # Only if Minitest 5.x is included / loaded do we need to worry about
+      # adding a shim for the new updates. Thus instead of checking on the
+      # RUBY_VERSION we need to check ancestors.
+      begin
+        # MiniTest is 4.x.
+        # Minitest is 5.x.
+        if ancestors.include?(::Minitest::Assertions)
+          require 'rspec/core/minitest_assertions_adapter'
+          include ::RSpec::Core::MinitestAssertionsAdapter
+        end
+      rescue NameError
+        # No-op. Minitest 5.x was not loaded.
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/version.rb b/rspec-core/lib/rspec/core/version.rb
new file mode 100644
index 0000000..095c858
--- /dev/null
+++ b/rspec-core/lib/rspec/core/version.rb
@@ -0,0 +1,9 @@
+module RSpec
+  module Core
+    # Version information for RSpec Core.
+    module Version
+      # Current version of RSpec Core, in semantic versioning format.
+      STRING = '3.2.2'
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/warnings.rb b/rspec-core/lib/rspec/core/warnings.rb
new file mode 100644
index 0000000..b880059
--- /dev/null
+++ b/rspec-core/lib/rspec/core/warnings.rb
@@ -0,0 +1,40 @@
+require "rspec/support/warnings"
+
+module RSpec
+  module Core
+    # @private
+    module Warnings
+      # @private
+      #
+      # Used internally to print deprecation warnings.
+      def deprecate(deprecated, data={})
+        RSpec.configuration.reporter.deprecation(
+          {
+            :deprecated => deprecated,
+            :call_site => CallerFilter.first_non_rspec_line
+          }.merge(data)
+        )
+      end
+
+      # @private
+      #
+      # Used internally to print deprecation warnings.
+      def warn_deprecation(message, opts={})
+        RSpec.configuration.reporter.deprecation opts.merge(:message => message)
+      end
+
+      # @private
+      def warn_with(message, options={})
+        if options[:use_spec_location_as_call_site]
+          message += "." unless message.end_with?(".")
+
+          if RSpec.current_example
+            message += " Warning generated from spec at `#{RSpec.current_example.location}`."
+          end
+        end
+
+        super(message, options)
+      end
+    end
+  end
+end
diff --git a/rspec-core/lib/rspec/core/world.rb b/rspec-core/lib/rspec/core/world.rb
new file mode 100644
index 0000000..307538e
--- /dev/null
+++ b/rspec-core/lib/rspec/core/world.rb
@@ -0,0 +1,167 @@
+module RSpec
+  module Core
+    # @api private
+    #
+    # Internal container for global non-configuration data.
+    class World
+      # @private
+      attr_reader :example_groups, :filtered_examples
+
+      # Used internally to determine what to do when a SIGINT is received.
+      attr_accessor :wants_to_quit
+
+      def initialize(configuration=RSpec.configuration)
+        @configuration = configuration
+        @example_groups = []
+        @filtered_examples = Hash.new do |hash, group|
+          hash[group] = begin
+            examples = group.examples.dup
+            examples = filter_manager.prune(examples)
+            examples.uniq!
+            examples
+          end
+        end
+      end
+
+      # @private
+      # Used internally to clear remaining groups when fail_fast is set.
+      def clear_remaining_example_groups
+        example_groups.clear
+      end
+
+      # @api private
+      #
+      # Apply ordering strategy from configuration to example groups.
+      def ordered_example_groups
+        ordering_strategy = @configuration.ordering_registry.fetch(:global)
+        ordering_strategy.order(@example_groups)
+      end
+
+      # @api private
+      #
+      # Reset world to 'scratch' before running suite.
+      def reset
+        example_groups.clear
+        @shared_example_group_registry = nil
+      end
+
+      # @private
+      def filter_manager
+        @configuration.filter_manager
+      end
+
+      # @api private
+      #
+      # Register an example group.
+      def register(example_group)
+        example_groups << example_group
+        example_group
+      end
+
+      # @private
+      def shared_example_group_registry
+        @shared_example_group_registry ||= SharedExampleGroup::Registry.new
+      end
+
+      # @private
+      def inclusion_filter
+        @configuration.inclusion_filter
+      end
+
+      # @private
+      def exclusion_filter
+        @configuration.exclusion_filter
+      end
+
+      # @api private
+      #
+      # Get count of examples to be run.
+      def example_count(groups=example_groups)
+        FlatMap.flat_map(groups) { |g| g.descendants }.
+          inject(0) { |a, e| a + e.filtered_examples.size }
+      end
+
+      # @api private
+      #
+      # Find line number of previous declaration.
+      def preceding_declaration_line(filter_line)
+        declaration_line_numbers.sort.inject(nil) do |highest_prior_declaration_line, line|
+          line <= filter_line ? line : highest_prior_declaration_line
+        end
+      end
+
+      # @private
+      def reporter
+        @configuration.reporter
+      end
+
+      # @api private
+      #
+      # Notify reporter of filters.
+      def announce_filters
+        filter_announcements = []
+
+        announce_inclusion_filter filter_announcements
+        announce_exclusion_filter filter_announcements
+
+        unless filter_manager.empty?
+          if filter_announcements.length == 1
+            reporter.message("Run options: #{filter_announcements[0]}")
+          else
+            reporter.message("Run options:\n  #{filter_announcements.join("\n  ")}")
+          end
+        end
+
+        if @configuration.run_all_when_everything_filtered? && example_count.zero?
+          reporter.message("#{everything_filtered_message}; ignoring #{inclusion_filter.description}")
+          filtered_examples.clear
+          inclusion_filter.clear
+        end
+
+        return unless example_count.zero?
+
+        example_groups.clear
+        if filter_manager.empty?
+          reporter.message("No examples found.")
+        elsif exclusion_filter.empty?
+          message = everything_filtered_message
+          if @configuration.run_all_when_everything_filtered?
+            message << "; ignoring #{inclusion_filter.description}"
+          end
+          reporter.message(message)
+        elsif inclusion_filter.empty?
+          reporter.message(everything_filtered_message)
+        end
+      end
+
+      # @private
+      def everything_filtered_message
+        "\nAll examples were filtered out"
+      end
+
+      # @api private
+      #
+      # Add inclusion filters to announcement message.
+      def announce_inclusion_filter(announcements)
+        return if inclusion_filter.empty?
+
+        announcements << "include #{inclusion_filter.description}"
+      end
+
+      # @api private
+      #
+      # Add exclusion filters to announcement message.
+      def announce_exclusion_filter(announcements)
+        return if exclusion_filter.empty?
+
+        announcements << "exclude #{exclusion_filter.description}"
+      end
+
+    private
+
+      def declaration_line_numbers
+        @declaration_line_numbers ||= FlatMap.flat_map(example_groups, &:declaration_line_numbers)
+      end
+    end
+  end
+end
diff --git a/rspec-core/maintenance-branch b/rspec-core/maintenance-branch
new file mode 100644
index 0000000..ad4dc0e
--- /dev/null
+++ b/rspec-core/maintenance-branch
@@ -0,0 +1 @@
+3-2-maintenance
diff --git a/rspec-core/rspec-core.gemspec b/rspec-core/rspec-core.gemspec
new file mode 100644
index 0000000..301dba5
--- /dev/null
+++ b/rspec-core/rspec-core.gemspec
@@ -0,0 +1,53 @@
+# -*- encoding: utf-8 -*-
+$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
+require "rspec/core/version"
+
+Gem::Specification.new do |s|
+  s.name        = "rspec-core"
+  s.version     = RSpec::Core::Version::STRING
+  s.platform    = Gem::Platform::RUBY
+  s.license     = "MIT"
+  s.authors     = ["Steven Baker", "David Chelimsky", "Chad Humphries", "Myron Marston"]
+  s.email       = "rspec at googlegroups.com"
+  s.homepage    = "http://github.com/rspec/rspec-core"
+  s.summary     = "rspec-core-#{RSpec::Core::Version::STRING}"
+  s.description = "BDD for Ruby. RSpec runner and example groups."
+
+  s.rubyforge_project  = "rspec"
+
+  s.files            = `git ls-files -- lib/*`.split("\n")
+  s.files           += %w[README.md License.txt Changelog.md .yardopts .document]
+  s.test_files       = []
+  s.bindir           = 'exe'
+  s.executables      = `git ls-files -- exe/*`.split("\n").map{ |f| File.basename(f) }
+  s.rdoc_options     = ["--charset=UTF-8"]
+  s.require_path     = "lib"
+
+  s.required_ruby_version = '>= 1.8.7'
+
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  if File.exist?(private_key)
+    s.signing_key = private_key
+    s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
+  end
+
+  if RSpec::Core::Version::STRING =~ /[a-zA-Z]+/
+    # rspec-support is locked to our version when running pre,rc etc
+    s.add_runtime_dependency "rspec-support", "= #{RSpec::Core::Version::STRING}"
+  else
+    # rspec-support must otherwise match our major/minor version
+    s.add_runtime_dependency "rspec-support", "~> #{RSpec::Core::Version::STRING.split('.')[0..1].concat(['0']).join('.')}"
+  end
+
+  s.add_development_dependency "rake",     "~> 10.0.0"
+  s.add_development_dependency "cucumber", "~> 1.3"
+  s.add_development_dependency "minitest", "~> 5.3"
+  s.add_development_dependency "aruba",    "~> 0.6"
+
+  s.add_development_dependency "nokogiri", (RUBY_VERSION < '1.9.3' ? "1.5.2" : "~> 1.5")
+  s.add_development_dependency "coderay",  "~> 1.0.9"
+
+  s.add_development_dependency "mocha",    "~> 0.13.0"
+  s.add_development_dependency "rr",       "~> 1.0.4"
+  s.add_development_dependency "flexmock", "~> 0.9.0"
+end
diff --git a/rspec-core/script/clone_all_rspec_repos b/rspec-core/script/clone_all_rspec_repos
new file mode 100755
index 0000000..f83d2e9
--- /dev/null
+++ b/rspec-core/script/clone_all_rspec_repos
@@ -0,0 +1,24 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+if is_mri; then
+  pushd ..
+
+  clone_repo "rspec"
+  clone_repo "rspec-core"
+  clone_repo "rspec-expectations"
+  clone_repo "rspec-mocks"
+  clone_repo "rspec-rails"
+
+  if rspec_support_compatible; then
+    clone_repo "rspec-support"
+  fi
+
+  popd
+else
+  echo "Not cloning all repos since we are not on MRI and they are only needed for the MRI build"
+fi
diff --git a/rspec-core/script/console b/rspec-core/script/console
new file mode 100755
index 0000000..cfab984
--- /dev/null
+++ b/rspec-core/script/console
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+require "irb"
+lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib")
+$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
+
+require 'rspec/core'
+
+IRB.start(__FILE__)
diff --git a/rspec-core/script/functions.sh b/rspec-core/script/functions.sh
new file mode 100644
index 0000000..a96a5c7
--- /dev/null
+++ b/rspec-core/script/functions.sh
@@ -0,0 +1,129 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $SCRIPT_DIR/travis_functions.sh
+source $SCRIPT_DIR/predicate_functions.sh
+
+# idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
+export JRUBY_OPTS="${JRUBY_OPTS} -X-C" # disable JIT since these processes are so short lived
+SPECS_HAVE_RUN_FILE=specs.out
+MAINTENANCE_BRANCH=`cat maintenance-branch`
+
+function clone_repo {
+  if [ ! -d $1 ]; then # don't clone if the dir is already there
+    travis_retry eval "git clone git://github.com/rspec/$1 --depth 1 --branch $MAINTENANCE_BRANCH"
+  fi;
+}
+
+function run_specs_and_record_done {
+  local rspec_bin=bin/rspec
+
+  # rspec-core needs to run with a special script that loads simplecov first,
+  # so that it can instrument rspec-core's code before rspec-core has been loaded.
+  if [ -f script/rspec_with_simplecov ]; then
+    rspec_bin=script/rspec_with_simplecov
+  fi;
+
+  echo "${PWD}/bin/rspec"
+  $rspec_bin spec --backtrace --format progress --profile --format progress --out $SPECS_HAVE_RUN_FILE
+}
+
+function run_cukes {
+  if [ -d features ]; then
+    # force jRuby to use client mode JVM or a compilation mode thats as close as possible,
+    # idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
+    #
+    # Note that we delay setting this until we run the cukes because we've seen
+    # spec failures in our spec suite due to problems with this mode.
+    export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
+
+    echo "${PWD}/bin/cucumber"
+
+    if is_mri_192; then
+      # For some reason we get SystemStackError on 1.9.2 when using
+      # the bin/cucumber approach below. That approach is faster
+      # (as it avoids the bundler tax), so we use it on rubies where we can.
+      bundle exec cucumber --strict
+    else
+      # Prepare RUBYOPT for scenarios that are shelling out to ruby,
+      # and PATH for those that are using `rspec` or `rake`.
+      RUBYOPT="-I${PWD}/../bundle -rbundler/setup" \
+         PATH="${PWD}/bin:$PATH" \
+         bin/cucumber --strict
+    fi
+  fi
+}
+
+function run_specs_one_by_one {
+  echo "Running each spec file, one-by-one..."
+
+  for file in `find spec -iname '*_spec.rb'`; do
+    bin/rspec $file -b --format progress
+  done
+}
+
+function run_spec_suite_for {
+  if [ ! -f ../$1/$SPECS_HAVE_RUN_FILE ]; then # don't rerun specs that have already run
+    echo "Running specs for $1"
+    pushd ../$1
+    unset BUNDLE_GEMFILE
+    bundle_install_flags=`cat .travis.yml | grep bundler_args | tr -d '"' | grep -o " .*"`
+    travis_retry eval "bundle install $bundle_install_flags"
+    run_specs_and_record_done
+    popd
+  fi;
+}
+
+function check_documentation_coverage {
+  echo "bin/yard stats --list-undoc"
+
+  bin/yard stats --list-undoc | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      coverage ||= line[/([\d\.]+)% documented/, 1]
+      puts line
+    end
+
+    unless Float(coverage) == 100
+      puts \"\n\nMissing documentation coverage (currently at #{coverage}%)\"
+      exit(1)
+    end
+
+    if has_warnings
+      puts \"\n\nYARD emitted documentation warnings.\"
+      exit(1)
+    end
+  "
+
+  # Some warnings only show up when generating docs, so do that as well.
+  bin/yard doc --no-cache | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      has_errors   ||= line.start_with?('[error]:')
+      puts line
+    end
+
+    if has_warnings || has_errors
+      puts \"\n\nYARD emitted documentation warnings or errors.\"
+      exit(1)
+    end
+  "
+}
+
+function check_style_and_lint {
+  echo "bin/rubucop lib"
+  bin/rubocop lib
+}
+
+function run_all_spec_suites {
+  fold "one-by-one specs" run_specs_one_by_one
+  fold "rspec-core specs" run_spec_suite_for "rspec-core"
+  fold "rspec-expectations specs" run_spec_suite_for "rspec-expectations"
+  fold "rspec-mocks specs" run_spec_suite_for "rspec-mocks"
+  fold "rspec-rails specs" run_spec_suite_for "rspec-rails"
+
+  if rspec_support_compatible; then
+    fold "rspec-support specs" run_spec_suite_for "rspec-support"
+  fi
+}
diff --git a/rspec-core/script/ignores b/rspec-core/script/ignores
new file mode 100644
index 0000000..07ae2b4
--- /dev/null
+++ b/rspec-core/script/ignores
@@ -0,0 +1,72 @@
+# grep -v -f <this file> doesn't work properly when empty, so this line is here.
+
+# The `alias_method` calls below are only executed at file load time
+# (when the method cache will be busted by defining methods anyway).
+lib/rspec/core/configuration.rb:        alias_method alias_name, name
+lib/rspec/core/configuration.rb:        alias_method "#{alias_name}=", "#{name}="
+lib/rspec/core/configuration.rb:        names.each {|name| alias_method "#{name}?", name}
+lib/rspec/core/configuration.rb:      alias_method :formatter=, :add_formatter
+lib/rspec/core/configuration.rb:      alias_method :alias_it_should_behave_like_to, :alias_it_behaves_like_to
+lib/rspec/core/configuration.rb:      alias_method :filter_run, :filter_run_including
+lib/rspec/core/configuration.rb:      alias_method :filter=, :inclusion_filter=
+lib/rspec/core/configuration.rb:      alias_method :filter, :inclusion_filter
+lib/rspec/core/example.rb:      alias_method :pending?, :pending
+lib/rspec/core/example_group.rb:        alias_method :display_name, :description
+lib/rspec/core/example_group.rb:        alias_method :describes, :described_class
+lib/rspec/core/example_group.rb:        # Works like `alias_method :name, :example` with the added benefit of
+lib/rspec/core/example_group.rb:        # Works like `alias_method :name, :it_behaves_like` with the added
+lib/rspec/core/example_group.rb:        alias_method :context, :describe
+lib/rspec/core/hooks.rb:      alias_method :append_before, :before
+lib/rspec/core/hooks.rb:      alias_method :prepend_after, :after
+lib/rspec/core/shared_example_group.rb:      alias_method :shared_context,      :shared_examples
+lib/rspec/core/shared_example_group.rb:      alias_method :share_examples_for,  :shared_examples
+lib/rspec/core/shared_example_group.rb:      alias_method :shared_examples_for, :shared_examples
+lib/rspec/core/shared_example_group.rb:        alias_method :shared_context,      :shared_examples
+lib/rspec/core/shared_example_group.rb:        alias_method :share_examples_for,  :shared_examples
+lib/rspec/core/shared_example_group.rb:        alias_method :shared_examples_for, :shared_examples
+lib/rspec/core/example_group.rb:        alias_method :describe, :example_group
+lib/rspec/core/example_group.rb:        alias_method :context, :example_group
+
+# The `alias_method` calls below happen when users define a named let.
+# It happens at spec definition time, not spec run time.
+lib/rspec/core/memoized_helpers.rb:            alias_method :subject, name
+
+# These `const_set` calls happen at spec definition time,
+# not at spec run time, so they are OK.
+lib/rspec/core/example_group.rb:      const_scope.const_set(name, group)
+lib/rspec/core/memoized_helpers.rb:              example_group.const_set(:NamedSubjectPreventSuper, self)
+lib/rspec/core/memoized_helpers.rb:          example_group.const_set(:LetDefinitions, mod)
+
+# These mentions of `extend` get executed at spec definition time
+# (unless the user changes their RSpec config at spec run time, but
+# there's no way to work around that).
+lib/rspec/core/configuration.rb:      def extend(mod, \*filters)
+lib/rspec/core/configuration.rb:        include_or_extend_modules << \[:extend, mod, Metadata.build_hash_from(filters)\]
+lib/rspec/core/configuration.rb:          host.extend(mod) unless host.singleton_class < mod
+lib/rspec/core/configuration.rb:          host.extend(mod) unless (class << host; self; end).included_modules.include?(mod)
+lib/rspec/core/configuration.rb:          extend RSpec::SharedContext
+lib/rspec/core/dsl.rb:extend RSpec::Core::DSL
+lib/rspec/core/example_group.rb:      extend  Hooks
+lib/rspec/core/example_group.rb:      extend SharedExampleGroup
+lib/rspec/core/memoized_helpers.rb:        mod.extend(ClassMethods)
+lib/rspec/core/shared_example_group.rb:extend RSpec::Core::SharedExampleGroup::TopLevelDSL
+
+# This use of `extend` only happens on 1.8.7, when a shared example group
+# is defined (to provide the Proc#source_location method on the provided
+# block). It should only happen at spec definition time (unless users are
+# defining shared example groups at spec run time).
+lib/rspec/core/shared_example_group.rb:            block.extend Module.new {
+
+# This happens when an example group is defined, not at spec run time.
+lib/rspec/core/example_group.rb:        subclass = Class.new(parent)
+
+# This happens at file load time.
+lib/rspec/core/formatters/deprecation_formatter.rb:    DeprecationError = Class.new(StandardError)
+
+# This enables / disable monkey patching and only happens on demand
+lib/rspec/core/dsl.rb:          change_global_dsl { undef_method method_name }
+lib/rspec/core/shared_example_group.rb:            undef shared_examples
+lib/rspec/core/shared_example_group.rb:            undef shared_context
+lib/rspec/core/shared_example_group.rb:            undef share_examples_for
+lib/rspec/core/shared_example_group.rb:            undef shared_examples_for
+lib/rspec/core/shared_example_group.rb:            undef shared_example_groups
diff --git a/rspec-core/script/list_method_cache_busters.sh b/rspec-core/script/list_method_cache_busters.sh
new file mode 100755
index 0000000..99805c6
--- /dev/null
+++ b/rspec-core/script/list_method_cache_busters.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# set -x
+
+# This list is from https://charlie.bz/blog/things-that-clear-rubys-method-cache
+
+IGNORE_FILE=/tmp/cache_busters_ignore
+COMMENT_LINE_RE="^(\w|\/)+\.rb: +#"
+
+cat script/ignores | grep -v "^$" | ruby -ne 'puts $_.split(/\s+###/)[0]' > $IGNORE_FILE
+
+egrep 'def [a-z]*\..*' -R lib | grep -v "def self" | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep undef -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep alias_method -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep remove_method -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep const_set -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep remove_const -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+egrep '\bextend\b' -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep 'Class.new' -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep private_constant -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep public_constant -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep "Marshal.load" -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep "OpenStruct.new" -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+
diff --git a/rspec-core/script/predicate_functions.sh b/rspec-core/script/predicate_functions.sh
new file mode 100644
index 0000000..fc5d372
--- /dev/null
+++ b/rspec-core/script/predicate_functions.sh
@@ -0,0 +1,64 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+function is_mri {
+  if ruby -e "exit(!defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby')"; then
+    # RUBY_ENGINE only returns 'ruby' on MRI.
+    # MRI 1.8.7 lacks the constant but all other rubies have it (including JRuby in 1.8 mode)
+    return 0
+  else
+    return 1
+  fi;
+}
+
+function is_mri_192 {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION == '1.9.2')"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function is_mri_2plus {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION.to_f > 2.0)"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function rspec_support_compatible {
+  if [ "$MAINTENANCE_BRANCH" != "2-99-maintenance" ] && [ "$MAINTENANCE_BRANCH" != "2-14-maintenance" ]; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+function documentation_enforced {
+  if [ -x ./bin/yard ]; then
+    if is_mri_2plus; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function style_and_lint_enforced {
+ if [ -x ./bin/rubocop ]; then
+   return 0
+ else
+   return 1
+ fi
+}
diff --git a/rspec-core/script/prevent_runtime_method_cache_busters b/rspec-core/script/prevent_runtime_method_cache_busters
new file mode 100755
index 0000000..b3cef8d
--- /dev/null
+++ b/rspec-core/script/prevent_runtime_method_cache_busters
@@ -0,0 +1,15 @@
+#!/usr/bin/env ruby
+
+method_cache_busters = `script/list_method_cache_busters.sh`.split("\n").map(&:chomp)
+
+if method_cache_busters.any?
+  puts "=" * 80
+  puts "Found #{method_cache_busters.size} new constructs that bust the method cache."
+  puts "These should be eliminated or added to the `ignores` file."
+  puts
+  puts "For more information, see https://charlie.bz/blog/things-that-clear-rubys-method-cache"
+  puts
+  puts method_cache_busters.join("\n")
+  puts "=" * 80
+  exit(1)
+end
diff --git a/rspec-core/script/regen_fixtures.sh b/rspec-core/script/regen_fixtures.sh
new file mode 100755
index 0000000..9985ca0
--- /dev/null
+++ b/rspec-core/script/regen_fixtures.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# This script likely won't work as is for you, but is a good template for
+# iterating over all rubies and regenerating HTML fixtures.
+
+set -e
+
+source /usr/local/share/chruby/chruby.sh
+
+function switch_ruby() {
+  chruby $1
+}
+
+function regen() {
+  bundle check || bundle install
+  GENERATE=1 bundle exec rspec ./spec/rspec/core/formatters/ || true
+}
+
+for ruby in \
+  jruby-1.7.9 \
+  1.9.3-p392 \
+  2.0.0-p247 \
+  2.1.0-p0 \
+  rbx-2.2.3 \
+  ree-1.8.7-2012.02;
+do
+  switch_ruby $ruby
+  ruby -v
+  if [ $(echo $ruby | grep jruby) ]
+  then
+    export JRUBY_OPTS=--1.8
+    regen
+    export JRUBY_OPTS=--1.9
+    regen
+  else
+    regen
+  fi
+done
+
diff --git a/rspec-core/script/rspec_with_simplecov b/rspec-core/script/rspec_with_simplecov
new file mode 100755
index 0000000..5c78675
--- /dev/null
+++ b/rspec-core/script/rspec_with_simplecov
@@ -0,0 +1,42 @@
+#!/usr/bin/env ruby
+
+# Turn on verbose to make sure we not generating any ruby warning
+$VERBOSE = true
+
+# So our "did they run the rspec command?" detection logic thinks
+# that we run `rspec`.
+$0 = "rspec"
+
+# This is necessary for when `--standalone` is being used.
+$:.unshift File.expand_path '../../bundle', __FILE__
+
+# For the travis build we put the bundle directory up a directory
+# so it can be shared among the repos for faster bundle installs.
+$:.unshift File.expand_path '../../../bundle', __FILE__
+
+require 'bundler/setup'
+
+# To use simplecov while running rspec-core's test suite, we must
+# load simplecov _before_ loading any of rspec-core's files.
+# So, this executable exists purely as a wrapper script that
+# first loads simplecov, and then loads rspec.
+begin
+  # Simplecov emits some ruby warnings when loaded, so silence them.
+  old_verbose, $VERBOSE = $VERBOSE, false
+
+  unless ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3'
+    require 'simplecov'
+
+    SimpleCov.start do
+      add_filter "./bundle/"
+      add_filter "./tmp/"
+      add_filter "./spec/"
+      minimum_coverage(RUBY_PLATFORM == 'java' ? 94 : 97)
+    end
+  end
+rescue LoadError
+ensure
+  $VERBOSE = old_verbose
+end
+
+load File.expand_path("../../exe/rspec", __FILE__)
diff --git a/rspec-core/script/run_build b/rspec-core/script/run_build
new file mode 100755
index 0000000..e1edcef
--- /dev/null
+++ b/rspec-core/script/run_build
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+# Allow repos to override the default functions and add their own
+if [ -f script/custom_build_functions.sh ]; then
+  source script/custom_build_functions.sh
+fi
+
+fold "specs" run_specs_and_record_done
+fold "cukes" run_cukes
+
+if documentation_enforced; then
+  fold "doc check" check_documentation_coverage
+fi
+
+if style_and_lint_enforced; then
+  fold "rubocop" check_style_and_lint
+fi
+
+if is_mri; then
+  run_all_spec_suites
+else
+  echo "Skipping the rest of the build on non-MRI rubies"
+fi
diff --git a/rspec-core/script/travis_functions.sh b/rspec-core/script/travis_functions.sh
new file mode 100644
index 0000000..77829b3
--- /dev/null
+++ b/rspec-core/script/travis_functions.sh
@@ -0,0 +1,69 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# Taken from:
+# https://github.com/travis-ci/travis-build/blob/e9314616e182a23e6a280199cd9070bfc7cae548/lib/travis/build/script/templates/header.sh#L34-L53
+travis_retry() {
+  local result=0
+  local count=1
+  while [ $count -le 3 ]; do
+    [ $result -ne 0 ] && {
+      echo -e "\n\033[33;1mThe command \"$@\" failed. Retrying, $count of 3.\033[0m\n" >&2
+    }
+    "$@"
+    result=$?
+    [ $result -eq 0 ] && break
+    count=$(($count + 1))
+    sleep 1
+  done
+
+  [ $count -eq 3 ] && {
+    echo "\n\033[33;1mThe command \"$@\" failed 3 times.\033[0m\n" >&2
+  }
+
+  return $result
+}
+
+# Taken from https://github.com/vcr/vcr/commit/fa96819c92b783ec0c794f788183e170e4f684b2
+# and https://github.com/vcr/vcr/commit/040aaac5370c68cd13c847c076749cd547a6f9b1
+nano_cmd="$(type -p gdate date | head -1)"
+nano_format="+%s%N"
+[ "$(uname -s)" != "Darwin" ] || nano_format="${nano_format/%N/000000000}"
+
+travis_time_start() {
+  travis_timer_id=$(printf %08x $(( RANDOM * RANDOM )))
+  travis_start_time=$($nano_cmd -u "$nano_format")
+  printf "travis_time:start:%s\r\e[0m" $travis_timer_id
+}
+
+travis_time_finish() {
+  local travis_end_time=$($nano_cmd -u "$nano_format")
+  local duration=$(($travis_end_time-$travis_start_time))
+  printf "travis_time:end:%s:start=%s,finish=%s,duration=%s\r\e[0m" \
+    $travis_timer_id $travis_start_time $travis_end_time $duration
+}
+
+fold() {
+  local name="$1"
+  local status=0
+  shift 1
+  if [ -n "$TRAVIS" ]; then
+    printf "travis_fold:start:%s\r\e[0m" "$name"
+    travis_time_start
+  fi
+
+  "$@"
+  status=$?
+
+  [ -z "$TRAVIS" ] || travis_time_finish
+
+  if [ "$status" -eq 0 ]; then
+    if [ -n "$TRAVIS" ]; then
+      printf "travis_fold:end:%s\r\e[0m" "$name"
+    fi
+  else
+    STATUS="$status"
+  fi
+
+  return $status
+}
diff --git a/rspec-core/spec/integration/filtering_spec.rb b/rspec-core/spec/integration/filtering_spec.rb
new file mode 100644
index 0000000..800ff90
--- /dev/null
+++ b/rspec-core/spec/integration/filtering_spec.rb
@@ -0,0 +1,148 @@
+require 'support/aruba_support'
+
+RSpec.describe 'Filtering' do
+  include_context "aruba support"
+  before { clean_current_dir }
+
+  it 'prints a rerun command for shared examples in external files that works to rerun' do
+    write_file "spec/support/shared_examples.rb", """
+      RSpec.shared_examples 'a failing example' do
+        example { expect(1).to eq(2) }
+      end
+    """
+
+    write_file "spec/host_group_spec.rb", """
+      load File.expand_path('../support/shared_examples.rb', __FILE__)
+
+      RSpec.describe 'A group with shared examples' do
+        include_examples 'a failing example'
+      end
+
+      RSpec.describe 'A group with a passing example' do
+        example { expect(1).to eq(1) }
+      end
+    """
+
+    run_command ""
+    expect(last_cmd_stdout).to include("2 examples, 1 failure")
+    run_rerun_command_for_failing_spec
+    expect(last_cmd_stdout).to include("1 example, 1 failure")
+    # There was originally a bug when doing it again...
+    run_rerun_command_for_failing_spec
+    expect(last_cmd_stdout).to include("1 example, 1 failure")
+  end
+
+  def run_rerun_command_for_failing_spec
+    command = last_cmd_stdout[/Failed examples:\s+rspec (\S+) #/, 1]
+    run_command command
+  end
+
+  context "with a shared example containing a context in a separate file" do
+    it "runs the example nested inside the shared" do
+      write_file_formatted 'spec/shared_example.rb', """
+        RSpec.shared_examples_for 'a shared example' do
+          it 'succeeds' do
+          end
+
+          context 'with a nested context' do
+            it 'succeeds (nested)' do
+            end
+          end
+        end
+      """
+
+      write_file_formatted 'spec/simple_spec.rb', """
+        require File.join(File.dirname(__FILE__), 'shared_example.rb')
+
+        RSpec.describe 'top level' do
+          it_behaves_like 'a shared example'
+        end
+      """
+
+      run_command 'spec/simple_spec.rb:3 -fd'
+      expect(last_cmd_stdout).to match(/2 examples, 0 failures/)
+    end
+  end
+
+  context "passing a line-number filter" do
+    it "trumps exclusions, except for :if/:unless (which are absolute exclusions)" do
+      write_file_formatted 'spec/a_spec.rb', """
+        RSpec.configure do |c|
+          c.filter_run_excluding :slow
+        end
+
+        RSpec.describe 'A slow group', :slow do
+          example('ex 1') { }
+          example('ex 2') { }
+        end
+
+        RSpec.describe 'A group with a slow example' do
+          example('ex 3'              ) { }
+          example('ex 4', :slow       ) { }
+          example('ex 5', :if => false) { }
+        end
+      """
+
+      run_command "spec/a_spec.rb -fd"
+      expect(last_cmd_stdout).to include("1 example, 0 failures", "ex 3").and exclude("ex 1", "ex 2", "ex 4", "ex 5")
+
+      run_command "spec/a_spec.rb:5 -fd" # selecting 'A slow group'
+      expect(last_cmd_stdout).to include("2 examples, 0 failures", "ex 1", "ex 2").and exclude("ex 3", "ex 4", "ex 5")
+
+      run_command "spec/a_spec.rb:12 -fd" # selecting slow example
+      expect(last_cmd_stdout).to include("1 example, 0 failures", "ex 4").and exclude("ex 1", "ex 2", "ex 3", "ex 5")
+
+      run_command "spec/a_spec.rb:13 -fd" # selecting :if => false example
+      expect(last_cmd_stdout).to include("0 examples, 0 failures").and exclude("ex 1", "ex 2", "ex 3", "ex 4", "ex 5")
+    end
+  end
+
+  context "passing a line-number-filtered file and a non-filtered file" do
+    it "applies the line number filtering only to the filtered file, running all specs in the non-filtered file except excluded ones" do
+      write_file_formatted "spec/file_1_spec.rb", """
+        RSpec.describe 'File 1' do
+          it('passes') {      }
+          it('fails')  { fail }
+        end
+      """
+
+      write_file_formatted "spec/file_2_spec.rb", """
+        RSpec.configure do |c|
+          c.filter_run_excluding :exclude_me
+        end
+
+        RSpec.describe 'File 2' do
+          it('passes') { }
+          it('passes') { }
+          it('fails', :exclude_me) { fail }
+        end
+      """
+
+      run_command "spec/file_1_spec.rb:2 spec/file_2_spec.rb -fd"
+      expect(last_cmd_stdout).to match(/3 examples, 0 failures/)
+      expect(last_cmd_stdout).not_to match(/fails/)
+    end
+
+    it 'applies command line tag filters only to files that lack a line number filter' do
+      write_file_formatted "spec/file_1_spec.rb", """
+        RSpec.describe 'File 1' do
+          it('is selected by line')   { }
+          it('is not selected', :tag) { }
+        end
+      """
+
+      write_file_formatted "spec/file_2_spec.rb", """
+        RSpec.describe 'File 2' do
+          it('is not selected')          { }
+          it('is selected by tag', :tag) { }
+        end
+      """
+
+      run_command "spec/file_1_spec.rb:2 spec/file_2_spec.rb --tag tag -fd"
+      expect(last_cmd_stdout).to include(
+        "2 examples, 0 failures",
+        "is selected by line", "is selected by tag"
+      ).and exclude("not selected")
+    end
+  end
+end
diff --git a/rspec-core/spec/integration/order_spec.rb b/rspec-core/spec/integration/order_spec.rb
new file mode 100644
index 0000000..5d5921e
--- /dev/null
+++ b/rspec-core/spec/integration/order_spec.rb
@@ -0,0 +1,204 @@
+require 'support/aruba_support'
+
+RSpec.describe 'command line', :ui do
+  include_context "aruba support"
+
+  before :all do
+    write_file 'spec/simple_spec.rb', """
+      RSpec.describe 'group 1' do
+        specify('group 1 example 1') {}
+        specify('group 1 example 2') {}
+        specify('group 1 example 3') {}
+        describe 'group 1-1' do
+          specify('group 1-1 example 1') {}
+          specify('group 1-1 example 2') {}
+          specify('group 1-1 example 3') {}
+        end
+      end
+    """
+
+    write_file 'spec/simple_spec2.rb', """
+      RSpec.describe 'group 2' do
+        specify('group 2 example 1') {}
+        specify('group 2 example 2') {}
+        specify('group 2 example 3') {}
+        describe 'group 2-1' do
+          specify('group 2-1 example 1') {}
+          specify('group 2-1 example 2') {}
+          specify('group 2-1 example 3') {}
+        end
+      end
+    """
+
+    write_file 'spec/order_spec.rb', """
+      RSpec.describe 'group 1' do
+        specify('group 1 example 1')  {}
+        specify('group 1 example 2')  {}
+        specify('group 1 example 3')  {}
+        specify('group 1 example 4')  {}
+        specify('group 1 example 5')  {}
+        specify('group 1 example 6')  {}
+        specify('group 1 example 7')  {}
+        specify('group 1 example 8')  {}
+        specify('group 1 example 9')  {}
+        specify('group 1 example 10') {}
+
+        describe 'group 1-1' do
+          specify('group 1-1 example 1')  {}
+          specify('group 1-1 example 2')  {}
+          specify('group 1-1 example 3')  {}
+          specify('group 1-1 example 4')  {}
+          specify('group 1-1 example 5')  {}
+          specify('group 1-1 example 6')  {}
+          specify('group 1-1 example 7')  {}
+          specify('group 1-1 example 8')  {}
+          specify('group 1-1 example 9')  {}
+          specify('group 1-1 example 10') {}
+        end
+
+        describe('group 1-2')  { specify('example') {} }
+        describe('group 1-3')  { specify('example') {} }
+        describe('group 1-4')  { specify('example') {} }
+        describe('group 1-5')  { specify('example') {} }
+        describe('group 1-6')  { specify('example') {} }
+        describe('group 1-7')  { specify('example') {} }
+        describe('group 1-8')  { specify('example') {} }
+        describe('group 1-9')  { specify('example') {} }
+        describe('group 1-10') { specify('example') {} }
+      end
+
+      RSpec.describe('group 2')  { specify('example') {} }
+      RSpec.describe('group 3')  { specify('example') {} }
+      RSpec.describe('group 4')  { specify('example') {} }
+      RSpec.describe('group 5')  { specify('example') {} }
+      RSpec.describe('group 6')  { specify('example') {} }
+      RSpec.describe('group 7')  { specify('example') {} }
+      RSpec.describe('group 8')  { specify('example') {} }
+      RSpec.describe('group 9')  { specify('example') {} }
+      RSpec.describe('group 10') { specify('example') {} }
+    """
+  end
+
+  describe '--order rand' do
+    it 'runs the examples and groups in a different order each time' do
+      run_command 'spec/order_spec.rb --order rand -f doc'
+      original_seed = srand
+      RSpec.configuration.seed = srand # reset seed in same process
+      run_command 'spec/order_spec.rb --order rand -f doc'
+      srand original_seed
+
+      expect(stdout.string).to match(/Randomized with seed \d+/)
+
+      top_level_groups      {|first_run, second_run| expect(first_run).to_not eq(second_run)}
+      nested_groups         {|first_run, second_run| expect(first_run).to_not eq(second_run)}
+      examples('group 1')   {|first_run, second_run| expect(first_run).to_not eq(second_run)}
+      examples('group 1-1') {|first_run, second_run| expect(first_run).to_not eq(second_run)}
+    end
+  end
+
+  describe '--order rand:SEED' do
+    it 'runs the examples and groups in the same order each time' do
+      2.times { run_command 'spec/order_spec.rb --order rand:123 -f doc' }
+
+      expect(stdout.string).to match(/Randomized with seed 123/)
+
+      top_level_groups      {|first_run, second_run| expect(first_run).to eq(second_run)}
+      nested_groups         {|first_run, second_run| expect(first_run).to eq(second_run)}
+      examples('group 1')   {|first_run, second_run| expect(first_run).to eq(second_run)}
+      examples('group 1-1') {|first_run, second_run| expect(first_run).to eq(second_run)}
+    end
+  end
+
+  describe '--seed SEED' do
+    it "forces '--order rand' and runs the examples and groups in the same order each time" do
+      2.times { run_command 'spec/order_spec.rb --seed 123 -f doc' }
+
+      expect(stdout.string).to match(/Randomized with seed 123/)
+
+      top_level_groups      {|first_run, second_run| expect(first_run).to eq(second_run)}
+      nested_groups         {|first_run, second_run| expect(first_run).to eq(second_run)}
+      examples('group 1')   {|first_run, second_run| expect(first_run).to eq(second_run)}
+      examples('group 1-1') {|first_run, second_run| expect(first_run).to eq(second_run)}
+    end
+
+    it "runs examples in the same order, regardless of the order in which files are given" do
+      run_command 'spec/simple_spec.rb spec/simple_spec2.rb --seed 1337 -f doc'
+      run_command 'spec/simple_spec2.rb spec/simple_spec.rb --seed 1337 -f doc'
+
+      top_level_groups      {|first_run, second_run| expect(first_run).to eq(second_run)}
+      nested_groups         {|first_run, second_run| expect(first_run).to eq(second_run)}
+    end
+  end
+
+  describe '--order defined on CLI with --order rand in .rspec' do
+    after { remove_file '.rspec' }
+
+    it "overrides --order rand with --order defined" do
+      write_file '.rspec', '--order rand'
+
+      run_command 'spec/order_spec.rb --order defined -f doc'
+
+      expect(stdout.string).not_to match(/Randomized/)
+
+      expect(stdout.string).to match(
+        /group 1.*group 1 example 1.*group 1 example 2.*group 1-1.*group 1-2.*group 2.*/m
+      )
+    end
+  end
+
+  context 'when a custom order is configured' do
+    after { remove_file 'spec/custom_order_spec.rb' }
+
+    before do
+      write_file 'spec/custom_order_spec.rb', """
+        RSpec.configure do |config|
+          config.register_ordering :global do |list|
+            list.sort_by { |item| item.description }
+          end
+        end
+
+        RSpec.describe 'group B' do
+          specify('group B example D')  {}
+          specify('group B example B')  {}
+          specify('group B example A')  {}
+          specify('group B example C')  {}
+        end
+
+        RSpec.describe 'group A' do
+          specify('group A example 1')  {}
+        end
+      """
+    end
+
+    it 'orders the groups and examples by the provided strategy' do
+      run_command 'spec/custom_order_spec.rb -f doc'
+
+      top_level_groups    { |groups| expect(groups.flatten).to eq(['group A', 'group B']) }
+      examples('group B') do |examples|
+        letters = examples.flatten.map { |e| e[/(.)\z/, 1] }
+        expect(letters).to eq(['A', 'B', 'C', 'D'])
+      end
+    end
+  end
+
+  def examples(group)
+    yield split_in_half(stdout.string.scan(/^\s+#{group} example.*$/))
+  end
+
+  def top_level_groups
+    yield example_groups_at_level(0)
+  end
+
+  def nested_groups
+    yield example_groups_at_level(2)
+  end
+
+  def example_groups_at_level(level)
+    split_in_half(stdout.string.scan(/^\s{#{level*2}}group.*$/))
+  end
+
+  def split_in_half(array)
+    length, midpoint = array.length, array.length / 2
+    return array.slice(0, midpoint), array.slice(midpoint, length)
+  end
+end
diff --git a/rspec-core/spec/rspec/core/backtrace_formatter_spec.rb b/rspec-core/spec/rspec/core/backtrace_formatter_spec.rb
new file mode 100644
index 0000000..133f121
--- /dev/null
+++ b/rspec-core/spec/rspec/core/backtrace_formatter_spec.rb
@@ -0,0 +1,304 @@
+module RSpec::Core
+  RSpec.describe BacktraceFormatter do
+    def make_backtrace_formatter(exclusion_patterns=nil, inclusion_patterns=nil)
+      BacktraceFormatter.new.tap do |bc|
+        bc.exclusion_patterns = exclusion_patterns if exclusion_patterns
+        bc.inclusion_patterns = inclusion_patterns if inclusion_patterns
+      end
+    end
+
+    describe "defaults" do
+      it "excludes rspec files" do
+        expect(make_backtrace_formatter.exclude?("/lib/rspec/core.rb")).to be true
+        expect(make_backtrace_formatter.exclude?("/lib/rspec/core/foo.rb")).to be true
+        expect(make_backtrace_formatter.exclude?("/lib/rspec/expectations/foo.rb")).to be true
+        expect(make_backtrace_formatter.exclude?("/lib/rspec/matchers/foo.rb")).to be true
+        expect(make_backtrace_formatter.exclude?("/lib/rspec/mocks/foo.rb")).to be true
+        expect(make_backtrace_formatter.exclude?("/lib/rspec/support/foo.rb")).to be true
+      end
+
+      it "excludes the rspec binary, even when rspec-core has installed as a bundler :git dependency" do
+        expect(make_backtrace_formatter.exclude?("exe/rspec")).to be true
+      end
+
+      it "excludes java files (for JRuby)", :if => (RUBY_PLATFORM == 'java')  do
+        expect(make_backtrace_formatter.exclude?("org/jruby/RubyArray.java:2336")).to be true
+      end
+
+      it "includes files in projects containing 'gems' in the name" do
+        expect(make_backtrace_formatter.exclude?('code/my-gems-plugin/lib/plugin.rb')).to be false
+      end
+
+      it "includes something in the current working directory" do
+        expect(make_backtrace_formatter.exclude?("#{Dir.getwd}/arbitrary")).to be false
+      end
+
+      it 'allows users to exclude their bundler vendor directory' do
+        formatter = make_backtrace_formatter([%r{/vendor/bundle/}])
+        vendored_gem_line = File.join(Dir.getwd, "vendor/bundle/gems/mygem-4.1.6/lib/my_gem:241")
+        expect(formatter.exclude? vendored_gem_line).to be true
+      end
+
+      context "when the exclusion list has been replaced" do
+        it "includes a line that the default patterns exclude" do
+          formatter = make_backtrace_formatter
+          expect {
+            formatter = make_backtrace_formatter([/spec_helper/])
+          }.to change { formatter.exclude? "/path/to/lib/rspec/expectations/foo.rb" }.from(true).to(false)
+        end
+      end
+
+      context "when the current working directory includes `gems` in the name" do
+        around(:example) do |ex|
+          Dir.mktmpdir do |tmp_dir|
+            dir = File.join(tmp_dir, "gems")
+            Dir.mkdir(dir)
+            Dir.chdir(dir, &ex)
+          end
+        end
+
+        it "includes something in the current working directory" do
+          expect(make_backtrace_formatter.exclude?("#{Dir.getwd}/arbitrary")).to be false
+        end
+      end
+    end
+
+    describe "#filter_gem" do
+      shared_examples_for "filtering a gem" do |gem_name, path|
+        it 'filters backtrace lines for the named gem' do
+          formatter = BacktraceFormatter.new
+          line      = File.join(path, "lib", "foo.rb:13")
+
+          expect {
+            formatter.filter_gem gem_name
+          }.to change { formatter.exclude?(line) }.from(false).to(true)
+        end
+      end
+
+      context "for a gem installed globally as a system gem" do
+        include_examples "filtering a gem", "foo",
+          "/Users/myron/.gem/ruby/2.1.1/gems/foo-1.6.3.1"
+      end
+
+      context "for a gem installed in a vendored bundler path" do
+        include_examples "filtering a gem", "foo",
+          "/Users/myron/code/my_project/bundle/ruby/2.1.0/gems/foo-0.3.6"
+      end
+
+      context "for a gem installed by bundler as a :git dependency" do
+        include_examples "filtering a gem", "foo",
+          "/Users/myron/code/my_project/bundle/ruby/2.1.0/bundler/gems/foo-2b826653e1f5"
+      end
+
+      context "for a gem sourced from a local path" do
+        include_examples "filtering a gem", "foo", "/Users/myron/code/foo"
+      end
+
+      context "when vendored under the working directory" do
+        include_examples "filtering a gem", "foo",
+          File.join(Dir.getwd, "bundle/ruby/2.1.0/bundler/gems/foo-0.3.6")
+      end
+    end
+
+    describe "#format_backtrace" do
+      it "excludes lines from rspec libs by default", :unless => RSpec::Support::OS.windows? do
+        backtrace = [
+          "/path/to/rspec-expectations/lib/rspec/expectations/foo.rb:37",
+          "/path/to/rspec-expectations/lib/rspec/matchers/foo.rb:37",
+          "./my_spec.rb:5",
+          "/path/to/rspec-mocks/lib/rspec/mocks/foo.rb:37",
+          "/path/to/rspec-core/lib/rspec/core/foo.rb:37"
+        ]
+
+        expect(BacktraceFormatter.new.format_backtrace(backtrace)).to eq(["./my_spec.rb:5"])
+      end
+
+      it "excludes lines from rspec libs by default", :failing_on_appveyor, :if => RSpec::Support::OS.windows? do
+        backtrace = [
+          "\\path\\to\\rspec-expectations\\lib\\rspec\\expectations\\foo.rb:37",
+          "\\path\\to\\rspec-expectations\\lib\\rspec\\matchers\\foo.rb:37",
+          ".\\my_spec.rb:5",
+          "\\path\\to\\rspec-mocks\\lib\\rspec\\mocks\\foo.rb:37",
+          "\\path\\to\\rspec-core\\lib\\rspec\\core\\foo.rb:37"
+        ]
+
+        expect(BacktraceFormatter.new.format_backtrace(backtrace)).to eq([".\\my_spec.rb:5"])
+      end
+
+      context "when every line is filtered out" do
+        let(:backtrace) do
+          [
+            "/path/to/rspec-expectations/lib/rspec/expectations/foo.rb:37",
+            "/path/to/rspec-expectations/lib/rspec/matchers/foo.rb:37",
+            "/path/to/rspec-mocks/lib/rspec/mocks/foo.rb:37",
+            "/path/to/rspec-core/lib/rspec/core/foo.rb:37"
+          ]
+        end
+
+        it "includes full backtrace" do
+          expect(BacktraceFormatter.new.format_backtrace(self.backtrace).take(4)).to eq self.backtrace
+        end
+
+        it "adds a message explaining everything was filtered" do
+          expect(BacktraceFormatter.new.format_backtrace(self.backtrace).drop(4).join).to match(/Showing full backtrace/)
+        end
+      end
+
+      context "when rspec is installed in the current working directory" do
+        it "excludes lines from rspec libs by default", :unless => RSpec::Support::OS.windows? do
+          backtrace = [
+            "#{Dir.getwd}/.bundle/path/to/rspec-expectations/lib/rspec/expectations/foo.rb:37",
+            "#{Dir.getwd}/.bundle/path/to/rspec-expectations/lib/rspec/matchers/foo.rb:37",
+            "#{Dir.getwd}/my_spec.rb:5",
+            "#{Dir.getwd}/.bundle/path/to/rspec-mocks/lib/rspec/mocks/foo.rb:37",
+            "#{Dir.getwd}/.bundle/path/to/rspec-core/lib/rspec/core/foo.rb:37"
+          ]
+
+          expect(BacktraceFormatter.new.format_backtrace(backtrace)).to eq(["./my_spec.rb:5"])
+        end
+      end
+    end
+
+    describe "#full_backtrace=true" do
+      it "sets full_backtrace true" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        formatter.full_backtrace = true
+        expect(formatter.full_backtrace?).to be true
+      end
+
+      it "preserves exclusion and inclusion patterns" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        formatter.full_backtrace = true
+        expect(formatter.exclusion_patterns).to eq [/discard/]
+        expect(formatter.inclusion_patterns).to eq [/keep/]
+      end
+
+      it "keeps all lines, even those that match exclusions" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        formatter.full_backtrace = true
+        expect(formatter.exclude? "discard").to be false
+      end
+    end
+
+    describe "#full_backtrace=false (after it was true)" do
+      it "sets full_backtrace false" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        formatter.full_backtrace = true
+        formatter.full_backtrace = false
+        expect(formatter.full_backtrace?).to be false
+      end
+
+      it "preserves exclusion and inclusion patterns" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        formatter.full_backtrace = true
+        formatter.full_backtrace = false
+        expect(formatter.exclusion_patterns).to eq [/discard/]
+        expect(formatter.inclusion_patterns).to eq [/keep/]
+      end
+
+      it "excludes lines that match exclusions" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        formatter.full_backtrace = true
+        formatter.full_backtrace = false
+        expect(formatter.exclude? "discard").to be true
+      end
+    end
+
+    describe "#backtrace_line" do
+      let(:formatter) { BacktraceFormatter.new }
+
+      it "trims current working directory" do
+        expect(self.formatter.__send__(:backtrace_line, File.expand_path(__FILE__))).to eq("./spec/rspec/core/backtrace_formatter_spec.rb")
+      end
+
+      it "preserves the original line" do
+        original_line = File.expand_path(__FILE__)
+        self.formatter.__send__(:backtrace_line, original_line)
+        expect(original_line).to eq(File.expand_path(__FILE__))
+      end
+
+      it "deals gracefully with a security error" do
+        safely do
+          self.formatter.__send__(:backtrace_line, __FILE__)
+          # on some rubies, this doesn't raise a SecurityError; this test just
+          # assures that if it *does* raise an error, the error is caught inside
+        end
+      end
+    end
+
+    context "when the current directory matches one of the default exclusion patterns" do
+      include_context "isolated directory"
+
+      around do |ex|
+        FileUtils.mkdir_p("bin")
+        Dir.chdir("./bin", &ex)
+      end
+
+      let(:line) { File.join(Dir.getwd, "foo.rb:13") }
+
+      it 'does not exclude lines from files in the current directory' do
+        expect(make_backtrace_formatter.exclude? self.line).to be false
+      end
+
+      context "with inclusion_patterns cleared" do
+        it 'excludes lines from files in the current directory' do
+          formatter = make_backtrace_formatter
+          formatter.inclusion_patterns.clear
+
+          expect(formatter.exclude? self.line).to be true
+        end
+      end
+    end
+
+    context "with no patterns" do
+      it "keeps all lines" do
+        lines = ["/tmp/a_file", "some_random_text", "hello\330\271!"]
+        formatter = make_backtrace_formatter([], [])
+        expect(lines.all? {|line| formatter.exclude? line}).to be false
+      end
+
+      it "is considered a full backtrace" do
+        expect(make_backtrace_formatter([], []).full_backtrace?).to be true
+      end
+    end
+
+    context "with an exclusion pattern but no inclusion patterns" do
+      it "excludes lines that match the exclusion pattern" do
+        formatter = make_backtrace_formatter([/discard/],[])
+        expect(formatter.exclude? "discard me").to be true
+      end
+
+      it "keeps lines that do not match the exclusion pattern" do
+        formatter = make_backtrace_formatter([/discard/],[])
+        expect(formatter.exclude? "apple").to be false
+      end
+
+      it "is considered a partial backtrace" do
+        formatter = make_backtrace_formatter([/discard/],[])
+        expect(formatter.full_backtrace?).to be false
+      end
+    end
+
+    context "with an exclusion pattern and an inclusion pattern" do
+      it "excludes lines that match the exclusion pattern but not the inclusion pattern" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        expect(formatter.exclude? "discard").to be true
+      end
+
+      it "keeps lines that match both patterns" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        expect(formatter.exclude? "discard/keep").to be false
+      end
+
+      it "keeps lines that match neither pattern" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        expect(formatter.exclude? "fish").to be false
+      end
+
+      it "is considered a partial backtrace" do
+        formatter = make_backtrace_formatter([/discard/],[/keep/])
+        expect(formatter.full_backtrace?).to be false
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/configuration_options_spec.rb b/rspec-core/spec/rspec/core/configuration_options_spec.rb
new file mode 100644
index 0000000..f0a3794
--- /dev/null
+++ b/rspec-core/spec/rspec/core/configuration_options_spec.rb
@@ -0,0 +1,426 @@
+require 'ostruct'
+require 'rspec/core/drb'
+
+RSpec.describe RSpec::Core::ConfigurationOptions, :isolated_directory => true, :isolated_home => true do
+  include ConfigOptionsHelper
+
+  it "warns when HOME env var is not set", :unless => (RUBY_PLATFORM == 'java' || RSpec::Support::OS.windows?) do
+    without_env_vars 'HOME' do
+      expect_warning_with_call_site(__FILE__, __LINE__ + 1)
+      RSpec::Core::ConfigurationOptions.new([]).options
+    end
+  end
+
+  it "does not mutate the provided args array" do
+    args = ['-e', 'some spec']
+    RSpec::Core::ConfigurationOptions.new(args).options
+    expect(args).to eq(['-e', 'some spec'])
+  end
+
+  describe "#configure" do
+    let(:config) { RSpec::Core::Configuration.new }
+
+    it "configures deprecation_stream before loading requires (since required files may issue deprecations)" do
+      opts = config_options_object(*%w[--deprecation-out path/to/log --require foo])
+      configuration = instance_double(RSpec::Core::Configuration).as_null_object
+
+      opts.configure(configuration)
+
+      expect(configuration).to have_received(:force).with(:deprecation_stream => "path/to/log").ordered
+      expect(configuration).to have_received(:requires=).ordered
+    end
+
+    it "configures deprecation_stream before configuring filter_manager" do
+      opts = config_options_object(*%w[--deprecation-out path/to/log --tag foo])
+      filter_manager = instance_double(RSpec::Core::FilterManager).as_null_object
+      configuration = instance_double(RSpec::Core::Configuration, :filter_manager => filter_manager).as_null_object
+
+      opts.configure(configuration)
+
+      expect(configuration).to have_received(:force).with(:deprecation_stream => "path/to/log").ordered
+      expect(filter_manager).to have_received(:include).with(:foo => true).ordered
+    end
+
+    it "configures deprecation_stream before configuring formatters" do
+      opts = config_options_object(*%w[--deprecation-out path/to/log --format doc])
+      configuration = instance_double(RSpec::Core::Configuration).as_null_object
+
+      opts.configure(configuration)
+
+      expect(configuration).to have_received(:force).with(:deprecation_stream => "path/to/log").ordered
+      expect(configuration).to have_received(:add_formatter).ordered
+    end
+
+    it "sends libs before requires" do
+      opts = config_options_object(*%w[--require a/path -I a/lib])
+      configuration = double("config").as_null_object
+      expect(configuration).to receive(:libs=).ordered
+      expect(configuration).to receive(:requires=).ordered
+      opts.configure(configuration)
+    end
+
+    it "loads requires before loading specs" do
+      opts = config_options_object(*%w[-rspec_helper])
+      expect(config).to receive(:requires=).ordered
+      expect(config).to receive(:get_files_to_run).ordered
+      opts.configure(config)
+      config.files_to_run
+    end
+
+    it "sets up load path and requires before formatter" do
+      opts = config_options_object(*%w[--require a/path -f a/formatter])
+      configuration = double("config").as_null_object
+      expect(configuration).to receive(:requires=).ordered
+      expect(configuration).to receive(:add_formatter).ordered
+      opts.configure(configuration)
+    end
+
+    it "sets default_path before loading specs" do
+      opts = config_options_object(*%w[--default-path spec])
+      expect(config).to receive(:force).with(:default_path => 'spec').ordered
+      expect(config).to receive(:get_files_to_run).ordered
+      opts.configure(config)
+      config.files_to_run
+    end
+
+    it "sets `files_or_directories_to_run` before `requires` so users can check `files_to_run` in a spec_helper loaded by `--require`" do
+      opts = config_options_object(*%w[--require spec_helper])
+      expect(config).to receive(:files_or_directories_to_run=).ordered
+      expect(config).to receive(:requires=).ordered
+      opts.configure(config)
+    end
+
+    it "sets default_path before `files_or_directories_to_run` since it relies on it" do
+      opts = config_options_object(*%w[--default-path spec])
+      expect(config).to receive(:force).with(:default_path => 'spec').ordered
+      expect(config).to receive(:files_or_directories_to_run=).ordered
+      opts.configure(config)
+    end
+
+    it 'configures the seed (via `order`) before requires so that required files can use the configured seed' do
+      opts = config_options_object(*%w[ --seed 1234 --require spec_helper ])
+
+      expect(config).to receive(:force).with(:order => "rand:1234").ordered
+      expect(config).to receive(:requires=).ordered
+
+      opts.configure(config)
+    end
+
+    { "pattern" => :pattern, "exclude-pattern" => :exclude_pattern }.each do |flag, attr|
+      it "sets #{attr} before `requires` so users can check `files_to_run` in a `spec_helper` loaded by `--require`" do
+        opts = config_options_object(*%W[--require spec_helpe --#{flag} **/*.spec])
+        expect(config).to receive(:force).with(attr => '**/*.spec').ordered
+        expect(config).to receive(:requires=).ordered
+        opts.configure(config)
+      end
+    end
+
+    it "assigns inclusion_filter" do
+      opts = config_options_object(*%w[--tag awesome])
+      opts.configure(config)
+      expect(config.inclusion_filter.rules).to have_key(:awesome)
+    end
+
+    it "merges the :exclusion_filter option with the default exclusion_filter" do
+      opts = config_options_object(*%w[--tag ~slow])
+      opts.configure(config)
+      expect(config.exclusion_filter.rules).to have_key(:slow)
+    end
+
+    it "forces color" do
+      opts = config_options_object(*%w[--color])
+      expect(config).to receive(:force).with(:color => true)
+      opts.configure(config)
+    end
+
+    [
+      ["--failure-exit-code", "3", :failure_exit_code, 3 ],
+      ["--pattern", "foo/bar", :pattern, "foo/bar"],
+      ["--failure-exit-code", "37", :failure_exit_code, 37],
+      ["--default-path", "behavior", :default_path, "behavior"],
+      ["--order", "rand", :order, "rand"],
+      ["--seed", "37", :order, "rand:37"],
+      ["--drb-port", "37", :drb_port, 37]
+    ].each do |cli_option, cli_value, config_key, config_value|
+      it "forces #{config_key}" do
+        opts = config_options_object(cli_option, cli_value)
+        expect(config).to receive(:force) do |pair|
+          expect(pair.keys.first).to eq(config_key)
+          expect(pair.values.first).to eq(config_value)
+        end
+        opts.configure(config)
+      end
+    end
+
+    it "merges --require specified by multiple configuration sources" do
+      with_env_vars 'SPEC_OPTS' => "--require file_from_env" do
+        opts = config_options_object(*%w[--require file_from_opts])
+        expect(config).to receive(:require).with("file_from_opts")
+        expect(config).to receive(:require).with("file_from_env")
+        opts.configure(config)
+      end
+    end
+
+    it "merges --I specified by multiple configuration sources" do
+      with_env_vars 'SPEC_OPTS' => "-I dir_from_env" do
+        opts = config_options_object(*%w[-I dir_from_opts])
+        expect(config).to receive(:libs=).with(["dir_from_opts", "dir_from_env"])
+        opts.configure(config)
+      end
+    end
+  end
+
+  describe "-c, --color, and --colour" do
+    it "sets :color => true" do
+      expect(parse_options('-c')).to include(:color => true)
+      expect(parse_options('--color')).to include(:color => true)
+      expect(parse_options('--colour')).to include(:color => true)
+    end
+  end
+
+  describe "--no-color" do
+    it "sets :color => false" do
+      expect(parse_options('--no-color')).to include(:color => false)
+    end
+
+    it "overrides previous :color => true" do
+      expect(parse_options('--color', '--no-color')).to include(:color => false)
+    end
+
+    it "gets overriden by a subsequent :color => true" do
+      expect(parse_options('--no-color', '--color')).to include(:color => true)
+    end
+  end
+
+  describe "-I" do
+    example "adds to :libs" do
+      expect(parse_options('-I', 'a_dir')).to include(:libs => ['a_dir'])
+    end
+    example "can be used more than once" do
+      expect(parse_options('-I', 'dir_1', '-I', 'dir_2')).to include(:libs => ['dir_1','dir_2'])
+    end
+  end
+
+  describe '--require' do
+    example "requires files" do
+      expect(parse_options('--require', 'a/path')).to include(:requires => ['a/path'])
+    end
+    example "can be used more than once" do
+      expect(parse_options('--require', 'path/1', '--require', 'path/2')).to include(:requires => ['path/1','path/2'])
+    end
+  end
+
+  describe "--format, -f" do
+    it "sets :formatter" do
+      [['--format', 'd'], ['-f', 'd'], '-fd'].each do |args|
+        expect(parse_options(*args)).to include(:formatters => [['d']])
+      end
+    end
+
+    example "can accept a class name" do
+      expect(parse_options('-fSome::Formatter::Class')).to include(:formatters => [['Some::Formatter::Class']])
+    end
+  end
+
+  describe "--profile, -p" do
+    it "sets :profile_examples" do
+      expect(parse_options('-p')).to include(:profile_examples => true)
+      expect(parse_options('--profile')).to include(:profile_examples => true)
+      expect(parse_options('-p', '4')).to include(:profile_examples => 4)
+      expect(parse_options('--profile', '3')).to include(:profile_examples => 3)
+    end
+  end
+
+  describe "--no-profile" do
+    it "sets :profile_examples to false" do
+      expect(parse_options('--no-profile')).to include(:profile_examples => false)
+    end
+  end
+
+  describe "--example" do
+    it "sets :full_description" do
+      expect(parse_options('--example','foo')).to include(:full_description => [/foo/])
+      expect(parse_options('-e','bar')).to include(:full_description => [/bar/])
+    end
+  end
+
+  describe "--backtrace, -b" do
+    it "sets full_backtrace on config" do
+      expect(parse_options("--backtrace")).to include(:full_backtrace => true)
+      expect(parse_options("-b")).to include(:full_backtrace => true)
+    end
+  end
+
+  describe "--fail-fast" do
+    it "defaults to false" do
+      expect(parse_options[:fail_fast]).to be_falsey
+    end
+
+    it "sets fail_fast on config" do
+      expect(parse_options("--fail-fast")[:fail_fast]).to be_truthy
+    end
+
+    it "sets fail_fast on config" do
+      expect(parse_options("--no-fail-fast")[:fail_fast]).to be_falsey
+    end
+  end
+
+  describe "--failure-exit-code" do
+    it "sets :failure_exit_code" do
+      expect(parse_options('--failure-exit-code', '0')).to include(:failure_exit_code => 0)
+      expect(parse_options('--failure-exit-code', '1')).to include(:failure_exit_code => 1)
+      expect(parse_options('--failure-exit-code', '2')).to include(:failure_exit_code => 2)
+    end
+
+    it "overrides previous :failure_exit_code" do
+      expect(parse_options('--failure-exit-code', '2', '--failure-exit-code', '3')).to include(:failure_exit_code => 3)
+    end
+  end
+
+  describe "--dry-run" do
+    it "defaults to false" do
+      expect(parse_options[:dry_run]).to be_falsey
+    end
+
+    it "sets dry_run on config" do
+      expect(parse_options("--dry-run")[:dry_run]).to be_truthy
+    end
+  end
+
+  describe "--options" do
+    it "sets :custom_options_file" do
+      expect(parse_options(*%w[-O my.opts])).to include(:custom_options_file => "my.opts")
+      expect(parse_options(*%w[--options my.opts])).to include(:custom_options_file => "my.opts")
+    end
+  end
+
+  describe "--no-drb" do
+    it "disables drb" do
+      expect(parse_options("--no-drb")).to include(:drb => false)
+    end
+
+    it "overrides a previous drb => true" do
+      expect(parse_options("--drb", "--no-drb")).to include(:drb => false)
+    end
+
+    it "gets overriden by a subsquent drb => true" do
+      expect(parse_options("--no-drb", "--drb")).to include(:drb => true)
+    end
+  end
+
+  describe "files_or_directories_to_run" do
+    it "parses files from '-c file.rb dir/file.rb'" do
+      expect(parse_options("-c", "file.rb", "dir/file.rb")).to include(
+        :files_or_directories_to_run => ["file.rb", "dir/file.rb"]
+      )
+    end
+
+    it "parses dir from 'dir'" do
+      expect(parse_options("dir")).to include(:files_or_directories_to_run => ["dir"])
+    end
+
+    it "parses dir and files from 'spec/file1_spec.rb, spec/file2_spec.rb'" do
+      expect(parse_options("dir", "spec/file1_spec.rb", "spec/file2_spec.rb")).to include(
+        :files_or_directories_to_run => ["dir", "spec/file1_spec.rb", "spec/file2_spec.rb"]
+      )
+    end
+
+    it "parses file names that look like `default-path` option" do
+      expect(parse_options("spec/default_path_spec.rb")).to include(
+        :files_or_directories_to_run => ["spec/default_path_spec.rb"]
+      )
+    end
+
+    it "provides no files or directories if spec directory does not exist" do
+      allow(FileTest).to receive(:directory?).with("spec").and_return false
+      expect(parse_options()).to include(:files_or_directories_to_run => [])
+    end
+  end
+
+  describe "default_path" do
+    it "gets set before files_or_directories_to_run" do
+      config = RSpec::Core::Configuration.new
+      expect(config).to receive(:force).with(:default_path => 'foo').ordered
+      expect(config).to receive(:get_files_to_run).ordered
+      opts = config_options_object("--default-path", "foo")
+      opts.configure(config)
+      config.files_to_run
+    end
+  end
+
+  describe "sources: ~/.rspec, ./.rspec, ./.rspec-local, custom, CLI, and SPEC_OPTS" do
+    it "merges global, local, SPEC_OPTS, and CLI" do
+      File.open("./.rspec", "w") {|f| f << "--require some_file"}
+      File.open("./.rspec-local", "w") {|f| f << "--format global"}
+      File.open(File.expand_path("~/.rspec"), "w") {|f| f << "--color"}
+      with_env_vars 'SPEC_OPTS' => "--example 'foo bar'" do
+        options = parse_options("--drb")
+        expect(options[:color]).to be_truthy
+        expect(options[:requires]).to eq(["some_file"])
+        expect(options[:full_description]).to eq([/foo\ bar/])
+        expect(options[:drb]).to be_truthy
+        expect(options[:formatters]).to eq([['global']])
+      end
+    end
+
+    it "prefers SPEC_OPTS over CLI" do
+      with_env_vars 'SPEC_OPTS' => "--format spec_opts" do
+        expect(parse_options("--format", "cli")[:formatters]).to eq([['spec_opts']])
+      end
+    end
+
+    it "prefers CLI over file options" do
+      File.open("./.rspec", "w") {|f| f << "--format project"}
+      File.open(File.expand_path("~/.rspec"), "w") {|f| f << "--format global"}
+      expect(parse_options("--format", "cli")[:formatters]).to eq([['cli']])
+    end
+
+    it "prefers CLI over file options for filter inclusion" do
+      File.open("./.rspec", "w") {|f| f << "--tag ~slow"}
+      opts = config_options_object("--tag", "slow")
+      config = RSpec::Core::Configuration.new
+      opts.configure(config)
+      expect(config.inclusion_filter.rules).to have_key(:slow)
+      expect(config.exclusion_filter.rules).not_to have_key(:slow)
+    end
+
+    it "prefers project file options over global file options" do
+      File.open("./.rspec", "w") {|f| f << "--format project"}
+      File.open(File.expand_path("~/.rspec"), "w") {|f| f << "--format global"}
+      expect(parse_options[:formatters]).to eq([['project']])
+    end
+
+    it "prefers local file options over project file options" do
+      File.open("./.rspec-local", "w") {|f| f << "--format local"}
+      File.open("./.rspec", "w") {|f| f << "--format global"}
+      expect(parse_options[:formatters]).to eq([['local']])
+    end
+
+    it "parses options file correctly if erb code has trimming options" do
+      File.open("./.rspec", "w") do |f|
+        f << "<% if true -%>\n"
+        f << "--format local\n"
+        f << "<%- end %>\n"
+      end
+
+      expect(parse_options[:formatters]).to eq([['local']])
+    end
+
+    context "with custom options file" do
+      it "ignores project and global options files" do
+        File.open("./.rspec", "w") {|f| f << "--format project"}
+        File.open(File.expand_path("~/.rspec"), "w") {|f| f << "--format global"}
+        File.open("./custom.opts", "w") {|f| f << "--color"}
+        options = parse_options("-O", "./custom.opts")
+        expect(options[:format]).to be_nil
+        expect(options[:color]).to be_truthy
+      end
+
+      it "parses -e 'full spec description'" do
+        File.open("./custom.opts", "w") {|f| f << "-e 'The quick brown fox jumps over the lazy dog'"}
+        options = parse_options("-O", "./custom.opts")
+        expect(options[:full_description]).to eq([/The\ quick\ brown\ fox\ jumps\ over\ the\ lazy\ dog/])
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/configuration_spec.rb b/rspec-core/spec/rspec/core/configuration_spec.rb
new file mode 100644
index 0000000..331d734
--- /dev/null
+++ b/rspec-core/spec/rspec/core/configuration_spec.rb
@@ -0,0 +1,2041 @@
+require 'tmpdir'
+require 'rspec/support/spec/in_sub_process'
+
+module RSpec::Core
+
+  RSpec.describe Configuration do
+    include RSpec::Support::InSubProcess
+
+    let(:config) { Configuration.new }
+    let(:exclusion_filter) { config.exclusion_filter.rules }
+    let(:inclusion_filter) { config.inclusion_filter.rules }
+
+    shared_examples_for "warning of deprecated `:example_group` during filtering configuration" do |method, *args|
+      it "issues a deprecation warning when filtering by `:example_group`" do
+        args << { :example_group => { :file_location => /spec\/unit/ } }
+        expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /:example_group/)
+        config.__send__(method, *args)
+      end
+    end
+
+    describe '#deprecation_stream' do
+      it 'defaults to standard error' do
+        expect($rspec_core_without_stderr_monkey_patch.deprecation_stream).to eq STDERR
+      end
+
+      it 'is configurable' do
+        io = double 'deprecation io'
+        config.deprecation_stream = io
+        expect(config.deprecation_stream).to eq io
+      end
+
+      context 'when the reporter has already been initialized' do
+        before do
+          config.reporter
+          allow(config).to receive(:warn)
+        end
+
+        it 'prints a notice indicating the reconfigured output_stream will be ignored' do
+          config.deprecation_stream = double("IO")
+          expect(config).to have_received(:warn).with(/deprecation_stream.*#{__FILE__}:#{__LINE__ - 1}/)
+        end
+
+        it 'does not change the value of `deprecation_stream`' do
+          value = config.deprecation_stream
+          config.deprecation_stream = double("IO")
+          expect(config.deprecation_stream).to equal(value)
+        end
+
+        it 'does not print a warning if set to the value it already has' do
+          config.deprecation_stream = config.deprecation_stream
+          expect(config).not_to have_received(:warn)
+        end
+      end
+    end
+
+    describe "#output_stream" do
+      it 'defaults to standard output' do
+        expect(config.output_stream).to eq $stdout
+      end
+
+      it 'is configurable' do
+        io = double 'output io'
+        config.output_stream = io
+        expect(config.output_stream).to eq io
+      end
+
+      context 'when the reporter has already been initialized' do
+        before do
+          config.reporter
+          allow(config).to receive(:warn)
+        end
+
+        it 'prints a notice indicating the reconfigured output_stream will be ignored' do
+          config.output_stream = StringIO.new
+          expect(config).to have_received(:warn).with(/output_stream.*#{__FILE__}:#{__LINE__ - 1}/)
+        end
+
+        it 'does not change the value of `output_stream`' do
+          config.output_stream = StringIO.new
+          expect(config.output_stream).to eq($stdout)
+        end
+
+        it 'does not print a warning if set to the value it already has' do
+          config.output_stream = config.output_stream
+          expect(config).not_to have_received(:warn)
+        end
+      end
+    end
+
+    describe "#requires=" do
+      def absolute_path_to(dir)
+        File.expand_path("../../../../#{dir}", __FILE__)
+      end
+
+      it 'adds `lib` to the load path' do
+        lib_dir = absolute_path_to("lib")
+        $LOAD_PATH.delete(lib_dir)
+
+        expect($LOAD_PATH).not_to include(lib_dir)
+        config.requires = []
+        expect($LOAD_PATH).to include(lib_dir)
+      end
+
+      it 'adds the configured `default_path` to the load path' do
+        config.default_path = 'features'
+        foo_dir = absolute_path_to("features")
+
+        expect($LOAD_PATH).not_to include(foo_dir)
+        config.requires = []
+        expect($LOAD_PATH).to include(foo_dir)
+      end
+
+      it 'stores the required files' do
+        expect(config).to receive(:require).with('a/path')
+        config.requires = ['a/path']
+        expect(config.requires).to eq ['a/path']
+      end
+
+      context "when `default_path` refers to a file rather than a directory" do
+        it 'does not add it to the load path' do
+          config.default_path = 'Rakefile'
+          config.requires = []
+          expect($LOAD_PATH).not_to include(match(/Rakefile/))
+        end
+      end
+    end
+
+    describe "#load_spec_files" do
+      it "loads files using load" do
+        config.files_to_run = ["foo.bar", "blah_spec.rb"]
+        expect(config).to receive(:load).twice
+        config.load_spec_files
+      end
+
+      it "loads each file once, even if duplicated in list" do
+        config.files_to_run = ["a_spec.rb", "a_spec.rb"]
+        expect(config).to receive(:load).once
+        config.load_spec_files
+      end
+    end
+
+    describe "#mock_framework" do
+      it "defaults to :rspec" do
+        expect(RSpec::Support).to receive(:require_rspec_core).with('mocking_adapters/rspec')
+        expect(config.mock_framework).to eq(MockingAdapters::RSpec)
+      end
+
+      context "when rspec-mocks is not installed" do
+        it 'gracefully falls back to :nothing' do
+          allow(RSpec::Support).to receive(:require_rspec_core).and_call_original
+          allow(RSpec::Support).to receive(:require_rspec_core).with('mocking_adapters/rspec').and_raise(LoadError)
+
+          expect(config.mock_framework).to eq(MockingAdapters::Null)
+        end
+      end
+    end
+
+    describe "#mock_framework="do
+      it "delegates to mock_with" do
+        expect(config).to receive(:mock_with).with(:rspec)
+        config.mock_framework = :rspec
+      end
+    end
+
+    shared_examples "a configurable framework adapter" do |m|
+      it "yields a config object if the framework_module supports it" do
+        custom_config = Struct.new(:custom_setting).new
+        mod = Module.new
+        allow(mod).to receive_messages(:configuration => custom_config)
+
+        config.send m, mod do |mod_config|
+          mod_config.custom_setting = true
+        end
+
+        expect(custom_config.custom_setting).to be_truthy
+      end
+
+      it "raises if framework module doesn't support configuration" do
+        mod = Module.new
+
+        expect {
+          config.send m, mod do |mod_config|
+          end
+        }.to raise_error(/must respond to `configuration`/)
+      end
+    end
+
+    describe "#mock_with" do
+      before { allow(config).to receive(:require) }
+
+      it_behaves_like "a configurable framework adapter", :mock_with
+
+      it "allows rspec-mocks to be configured with a provided block" do
+        mod = Module.new
+
+        expect(RSpec::Mocks.configuration).to receive(:add_stub_and_should_receive_to).with(mod)
+
+        config.mock_with :rspec do |c|
+          c.add_stub_and_should_receive_to mod
+        end
+      end
+
+      context "with a module" do
+        it "sets the mock_framework_adapter to that module" do
+          mod = Module.new
+          config.mock_with mod
+          expect(config.mock_framework).to eq(mod)
+        end
+      end
+
+      it 'uses the named adapter' do
+        expect(RSpec::Support).to receive(:require_rspec_core).with('mocking_adapters/mocha')
+        stub_const("RSpec::Core::MockingAdapters::Mocha", Module.new)
+        config.mock_with :mocha
+      end
+
+      it "uses the null adapter when given :nothing" do
+        expect(RSpec::Support).to receive(:require_rspec_core).with('mocking_adapters/null').and_call_original
+        config.mock_with :nothing
+      end
+
+      it "raises an error when given an unknown key" do
+        expect {
+          config.mock_with :crazy_new_mocking_framework_ive_not_yet_heard_of
+        }.to raise_error(ArgumentError, /unknown mocking framework/i)
+      end
+
+      it "raises an error when given another type of object" do
+        expect {
+          config.mock_with Object.new
+        }.to raise_error(ArgumentError, /unknown mocking framework/i)
+      end
+
+      context 'when there are already some example groups defined' do
+        before { allow(RSpec::Support).to receive(:require_rspec_core) }
+
+        it 'raises an error since this setting must be applied before any groups are defined' do
+          allow(RSpec.world).to receive(:example_groups).and_return([double.as_null_object])
+          mocha = stub_const("RSpec::Core::MockingAdapters::Mocha", Module.new)
+          allow(mocha).to receive_messages(:framework_name => :mocha)
+
+          expect {
+            config.mock_with :mocha
+          }.to raise_error(/must be configured before any example groups are defined/)
+        end
+
+        it 'does not raise an error if the default `mock_with :rspec` is re-configured' do
+          config.mock_framework # called by RSpec when configuring the first example group
+          allow(RSpec.world).to receive(:example_groups).and_return([double.as_null_object])
+          config.mock_with :rspec
+        end
+
+        it 'does not raise an error if re-setting the same config' do
+          mocha = stub_const("RSpec::Core::MockingAdapters::Mocha", Module.new)
+          allow(mocha).to receive_messages(:framework_name => :mocha)
+
+          groups = []
+          allow(RSpec.world).to receive_messages(:example_groups => groups)
+          config.mock_with :mocha
+          groups << double.as_null_object
+          config.mock_with :mocha
+        end
+      end
+    end
+
+    describe "#expectation_frameworks" do
+      it "defaults to :rspec" do
+        expect(config).to receive(:require).with('rspec/expectations')
+        expect(config.expectation_frameworks).to eq([RSpec::Matchers])
+      end
+
+      context "when rspec-expectations is not installed" do
+        def an_anonymous_module
+          name = RUBY_VERSION.to_f < 1.9 ? '' : nil
+          an_object_having_attributes(:class => Module, :name => name)
+        end
+
+        it 'gracefully falls back to an anonymous module' do
+          allow(config).to receive(:require).with('rspec/expectations').and_raise(LoadError)
+          expect(config.expectation_frameworks).to match([an_anonymous_module])
+        end
+      end
+    end
+
+    describe "#expectation_framework=" do
+      it "delegates to expect_with" do
+        expect(config).to receive(:expect_with).with(:rspec)
+        config.expectation_framework = :rspec
+      end
+    end
+
+    def stub_expectation_adapters
+      stub_const("Test::Unit::Assertions", Module.new)
+      stub_const("Minitest::Assertions", Module.new)
+      stub_const("RSpec::Core::TestUnitAssertionsAdapter", Module.new)
+      stub_const("RSpec::Core::MinitestAssertionsAdapter", Module.new)
+      allow(config).to receive(:require)
+    end
+
+    describe "#expect_with" do
+      before do
+        stub_expectation_adapters
+      end
+
+      it_behaves_like "a configurable framework adapter", :expect_with
+
+      context "with :rspec" do
+        it "requires rspec/expectations" do
+          expect(config).to receive(:require).with('rspec/expectations')
+          config.expect_with :rspec
+        end
+
+        it "sets the expectation framework to ::RSpec::Matchers" do
+          config.expect_with :rspec
+          expect(config.expectation_frameworks).to eq [::RSpec::Matchers]
+        end
+      end
+
+      context "with :test_unit" do
+        it "requires rspec/core/test_unit_assertions_adapter" do
+          expect(config).to receive(:require).
+            with('rspec/core/test_unit_assertions_adapter')
+          config.expect_with :test_unit
+        end
+
+        it "sets the expectation framework to ::Test::Unit::Assertions" do
+          config.expect_with :test_unit
+          expect(config.expectation_frameworks).to eq [
+            ::RSpec::Core::TestUnitAssertionsAdapter
+          ]
+        end
+      end
+
+      context "with :minitest" do
+        it "requires rspec/core/minitest_assertions_adapter" do
+          expect(config).to receive(:require).
+            with('rspec/core/minitest_assertions_adapter')
+          config.expect_with :minitest
+        end
+
+        it "sets the expectation framework to ::Minitest::Assertions" do
+          config.expect_with :minitest
+          expect(config.expectation_frameworks).to eq [
+            ::RSpec::Core::MinitestAssertionsAdapter
+          ]
+        end
+      end
+
+      it "supports multiple calls" do
+        config.expect_with :rspec
+        config.expect_with :minitest
+        expect(config.expectation_frameworks).to eq [
+          RSpec::Matchers,
+          RSpec::Core::MinitestAssertionsAdapter
+        ]
+      end
+
+      it "raises if block given with multiple args" do
+        expect {
+          config.expect_with :rspec, :minitest do |mod_config|
+          end
+        }.to raise_error(/expect_with only accepts/)
+      end
+
+      it "raises ArgumentError if framework is not supported" do
+        expect do
+          config.expect_with :not_supported
+        end.to raise_error(ArgumentError)
+      end
+
+      context 'when there are already some example groups defined' do
+        it 'raises an error since this setting must be applied before any groups are defined' do
+          allow(RSpec.world).to receive(:example_groups).and_return([double.as_null_object])
+          expect {
+            config.expect_with :rspec
+          }.to raise_error(/must be configured before any example groups are defined/)
+        end
+
+        it 'does not raise an error if the default `expect_with :rspec` is re-configured' do
+          config.expectation_frameworks # called by RSpec when configuring the first example group
+          allow(RSpec.world).to receive(:example_groups).and_return([double.as_null_object])
+          config.expect_with :rspec
+        end
+
+        it 'does not raise an error if re-setting the same config' do
+          groups = []
+          allow(RSpec.world).to receive_messages(:example_groups => groups)
+          config.expect_with :minitest
+          groups << double.as_null_object
+          config.expect_with :minitest
+        end
+      end
+    end
+
+    describe "#files_to_run" do
+      it "loads files not following pattern if named explicitly" do
+        assign_files_or_directories_to_run "spec/rspec/core/resources/a_bar.rb"
+        expect(config.files_to_run).to contain_files("spec/rspec/core/resources/a_bar.rb")
+      end
+
+      it "prevents repetition of dir when start of the pattern" do
+        config.pattern = "spec/**/a_spec.rb"
+        assign_files_or_directories_to_run "spec"
+        expect(config.files_to_run).to contain_files("spec/rspec/core/resources/a_spec.rb")
+      end
+
+      it "does not prevent repetition of dir when later of the pattern" do
+        config.pattern = "rspec/**/a_spec.rb"
+        assign_files_or_directories_to_run "spec"
+        expect(config.files_to_run).to contain_files("spec/rspec/core/resources/a_spec.rb")
+      end
+
+      it "supports patterns starting with ./" do
+        config.pattern = "./spec/**/a_spec.rb"
+        assign_files_or_directories_to_run "spec"
+        expect(config.files_to_run).to contain_files("./spec/rspec/core/resources/a_spec.rb")
+      end
+
+      it "supports absolute path patterns", :failing_on_appveyor,
+        :pending => false,
+        :skip => (ENV['APPVEYOR'] ? "Failing on AppVeyor but :pending isn't working for some reason" : false) do
+        dir = File.expand_path("../resources", __FILE__)
+        config.pattern = File.join(dir, "**/*_spec.rb")
+        assign_files_or_directories_to_run "spec"
+
+        expect(config.files_to_run).to contain_files(
+          "./spec/rspec/core/resources/acceptance/foo_spec.rb",
+          "./spec/rspec/core/resources/a_spec.rb"
+        )
+      end
+
+      it "supports relative path patterns for an alternate directory from `spec`" do
+        Dir.chdir("./spec/rspec/core") do
+          config.pattern = "resources/**/*_spec.rb"
+          assign_files_or_directories_to_run "spec" # default dir
+
+          expect(config.files_to_run).to contain_files(
+            "resources/acceptance/foo_spec.rb",
+            "resources/a_spec.rb"
+          )
+        end
+      end
+
+      it "does not attempt to treat the pattern relative to `.` if it uses `**` in the first path segment as that would cause it load specs from vendored gems" do
+        Dir.chdir("./spec/rspec/core") do
+          config.pattern = "**/*_spec.rb"
+          assign_files_or_directories_to_run "spec" # default dir
+
+          expect(config.files_to_run).to contain_files()
+        end
+      end
+
+      it 'reloads when `files_or_directories_to_run` is reassigned' do
+        config.pattern = "spec/**/a_spec.rb"
+        config.files_or_directories_to_run = "empty_dir"
+
+        expect {
+          config.files_or_directories_to_run = "spec"
+        }.to change { config.files_to_run }.
+          to(a_file_collection("spec/rspec/core/resources/a_spec.rb"))
+      end
+
+      it 'attempts to load the provided file names' do
+        assign_files_or_directories_to_run "path/to/some/file.rb"
+        expect(config.files_to_run).to eq(["path/to/some/file.rb"])
+      end
+
+      it 'does not attempt to load a file at the `default_path`' do
+        config.default_path = "path/to/dir"
+        assign_files_or_directories_to_run "path/to/dir"
+        expect(config.files_to_run).to eq([])
+      end
+
+      context "with <path>:<line_number>" do
+        it "overrides inclusion filters set before config" do
+          config.force(:inclusion_filter => {:foo => :bar})
+          assign_files_or_directories_to_run "path/to/file.rb:37"
+          expect(inclusion_filter.size).to eq(1)
+          expect(inclusion_filter[:locations].keys.first).to match(/path\/to\/file\.rb$/)
+          expect(inclusion_filter[:locations].values.first).to eq([37])
+        end
+
+        it "clears exclusion filters set before config" do
+          config.force(:exclusion_filter => { :foo => :bar })
+          assign_files_or_directories_to_run "path/to/file.rb:37"
+          expect(config.exclusion_filter).to be_empty,
+            "expected exclusion filter to be empty:\n#{config.exclusion_filter}"
+        end
+      end
+
+      context "with default pattern" do
+        it "loads files named _spec.rb" do
+          assign_files_or_directories_to_run "spec/rspec/core/resources"
+          expect(config.files_to_run).to contain_files("spec/rspec/core/resources/a_spec.rb", "spec/rspec/core/resources/acceptance/foo_spec.rb")
+        end
+
+        it "loads files in Windows", :if => RSpec::Support::OS.windows? do
+          assign_files_or_directories_to_run "C:\\path\\to\\project\\spec\\sub\\foo_spec.rb"
+          expect(config.files_to_run).to contain_files("C:/path/to/project/spec/sub/foo_spec.rb")
+        end
+
+        it "loads files in Windows when directory is specified", :failing_on_appveyor, :if => RSpec::Support::OS.windows? do
+          assign_files_or_directories_to_run "spec\\rspec\\core\\resources"
+          expect(config.files_to_run).to contain_files("spec/rspec/core/resources/a_spec.rb")
+        end
+
+        it_behaves_like "handling symlinked directories when loading spec files" do
+          def loaded_files
+            assign_files_or_directories_to_run "spec"
+            config.files_to_run
+          end
+        end
+      end
+
+      context "with default default_path" do
+        it "loads files in the default path when run by rspec" do
+          allow(config).to receive(:command) { 'rspec' }
+          assign_files_or_directories_to_run []
+          expect(config.files_to_run).not_to be_empty
+        end
+
+        it "loads files in the default path when run with DRB (e.g., spork)" do
+          allow(config).to receive(:command) { 'spork' }
+          allow(RSpec::Core::Runner).to receive(:running_in_drb?) { true }
+          assign_files_or_directories_to_run []
+          expect(config.files_to_run).not_to be_empty
+        end
+
+        it "does not load files in the default path when run by ruby" do
+          allow(config).to receive(:command) { 'ruby' }
+          assign_files_or_directories_to_run []
+          expect(config.files_to_run).to be_empty
+        end
+      end
+
+      def specify_consistent_ordering_of_files_to_run
+        allow(File).to receive(:directory?).and_call_original
+        allow(File).to receive(:directory?).with('a') { true }
+        globbed_files = nil
+        allow(Dir).to receive(:[]).with(/^\{?a/) { globbed_files }
+        allow(Dir).to receive(:[]).with(a_string_starting_with(Dir.getwd)) { [] }
+
+        orderings = [
+          %w[ a/1.rb a/2.rb a/3.rb ],
+          %w[ a/2.rb a/1.rb a/3.rb ],
+          %w[ a/3.rb a/2.rb a/1.rb ]
+        ].map do |files|
+          globbed_files = files
+          yield
+          config.files_to_run
+        end
+
+        expect(orderings.uniq.size).to eq(1)
+      end
+
+      context 'when the given directories match the pattern' do
+        it 'orders the files in a consistent ordering, regardless of the underlying OS ordering' do
+          specify_consistent_ordering_of_files_to_run do
+            config.pattern = 'a/*.rb'
+            assign_files_or_directories_to_run 'a'
+          end
+        end
+      end
+
+      context 'when the pattern is given relative to the given directories' do
+        it 'orders the files in a consistent ordering, regardless of the underlying OS ordering' do
+          specify_consistent_ordering_of_files_to_run do
+            config.pattern = '*.rb'
+            assign_files_or_directories_to_run 'a'
+          end
+        end
+      end
+
+      context 'when given multiple file paths' do
+        it 'orders the files in a consistent ordering, regardless of the given order' do
+          allow(File).to receive(:directory?) { false } # fake it into thinking these a full file paths
+
+          files = ['a/b/c_spec.rb', 'c/b/a_spec.rb']
+          assign_files_or_directories_to_run(*files)
+          ordering_1 = config.files_to_run
+
+          assign_files_or_directories_to_run(*files.reverse)
+          ordering_2 = config.files_to_run
+
+          expect(ordering_1).to eq(ordering_2)
+        end
+      end
+    end
+
+    describe "#pattern" do
+      context "with single pattern" do
+        before { config.pattern = "**/*_foo.rb" }
+
+        it "loads all explicitly specified files, even those that do not match the pattern" do
+          file_1 = File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb")
+          file_2 = File.expand_path(File.dirname(__FILE__) + "/resources/a_bar.rb")
+
+          assign_files_or_directories_to_run file_1, file_2
+          expect(config.files_to_run).to contain_exactly(file_1, file_2)
+        end
+
+        it "loads files in directories following pattern" do
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).to include("#{dir}/a_foo.rb")
+        end
+
+        it "does not load files in directories not following pattern" do
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).not_to include("#{dir}/a_bar.rb")
+        end
+
+        it "ignores pattern if files are specified" do
+          files = [
+            File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb"),
+            File.expand_path(File.dirname(__FILE__) + "/resources/a_spec.rb")
+          ]
+          assign_files_or_directories_to_run(files)
+          expect(config.files_to_run).to match_array(files)
+        end
+      end
+
+      context "with multiple patterns" do
+        it "supports comma separated values" do
+          config.pattern = "**/*_foo.rb,**/*_bar.rb"
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).to include("#{dir}/a_foo.rb")
+          expect(config.files_to_run).to include("#{dir}/a_bar.rb")
+        end
+
+        it "supports comma separated values with spaces" do
+          config.pattern = "**/*_foo.rb, **/*_bar.rb"
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).to include("#{dir}/a_foo.rb")
+          expect(config.files_to_run).to include("#{dir}/a_bar.rb")
+        end
+
+        it "supports curly braces glob syntax" do
+          config.pattern = "**/*_{foo,bar}.rb"
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).to include("#{dir}/a_foo.rb")
+          expect(config.files_to_run).to include("#{dir}/a_bar.rb")
+        end
+      end
+
+      context "after files have already been loaded" do
+        it 'warns that it will have no effect' do
+          expect_warning_with_call_site(__FILE__, __LINE__ + 2, /has no effect/)
+          config.load_spec_files
+          config.pattern = "rspec/**/*.spec"
+        end
+
+        it 'does not warn if reset is called after load_spec_files' do
+          config.load_spec_files
+          config.reset
+          expect(RSpec).to_not receive(:warning)
+          config.pattern = "rspec/**/*.spec"
+        end
+      end
+
+      context "after `files_to_run` has been accessed but before files have been loaded" do
+        it 'still takes affect' do
+          file = File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb")
+          assign_files_or_directories_to_run File.dirname(file)
+          expect(config.files_to_run).not_to include(file)
+          config.pattern = "**/*_foo.rb"
+          expect(config.files_to_run).to include(file)
+        end
+      end
+    end
+
+    describe "#exclude_pattern" do
+      context "with single pattern" do
+        before { config.exclude_pattern = "**/*_foo.rb" }
+
+        it "does not load files in directories following exclude pattern" do
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).not_to include("#{dir}/a_foo.rb")
+        end
+
+        it "loads files in directories not following exclude pattern" do
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).to include("#{dir}/a_spec.rb")
+        end
+
+        it "ignores exclude_pattern if files are specified" do
+          files = [
+            File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb"),
+            File.expand_path(File.dirname(__FILE__) + "/resources/a_spec.rb")
+          ]
+          assign_files_or_directories_to_run(files)
+          expect(config.files_to_run).to match_array(files)
+        end
+      end
+
+      context "with multiple patterns" do
+        it "supports comma separated values" do
+          config.exclude_pattern = "**/*_foo.rb,**/*_bar.rb"
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).not_to include("#{dir}/a_foo.rb")
+          expect(config.files_to_run).not_to include("#{dir}/a_bar.rb")
+        end
+
+        it "supports comma separated values with spaces" do
+          config.exclude_pattern = "**/*_foo.rb, **/*_bar.rb"
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).not_to include("#{dir}/a_foo.rb")
+          expect(config.files_to_run).not_to include("#{dir}/a_bar.rb")
+        end
+
+        it "supports curly braces glob syntax" do
+          config.exclude_pattern = "**/*_{foo,bar}.rb"
+          dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+          assign_files_or_directories_to_run dir
+          expect(config.files_to_run).not_to include("#{dir}/a_foo.rb")
+          expect(config.files_to_run).not_to include("#{dir}/a_bar.rb")
+        end
+      end
+
+      context "after files have already been loaded" do
+        it 'warns that it will have no effect' do
+          expect_warning_with_call_site(__FILE__, __LINE__ + 2, /has no effect/)
+          config.load_spec_files
+          config.exclude_pattern = "rspec/**/*.spec"
+        end
+
+        it 'does not warn if reset is called after load_spec_files' do
+          config.load_spec_files
+          config.reset
+          expect(RSpec).to_not receive(:warning)
+          config.exclude_pattern = "rspec/**/*.spec"
+        end
+      end
+
+      context "after `files_to_run` has been accessed but before files have been loaded" do
+        it 'still takes affect' do
+          config.pattern = "**/*.rb"
+          file = File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb")
+          assign_files_or_directories_to_run File.dirname(file)
+          expect(config.files_to_run).to include(file)
+          config.exclude_pattern = "**/*_foo.rb"
+          expect(config.files_to_run).not_to include(file)
+        end
+      end
+    end
+
+    describe "path with line number" do
+      it "assigns the line number as a location filter" do
+        assign_files_or_directories_to_run "path/to/a_spec.rb:37"
+        expect(inclusion_filter).to eq({:locations => {File.expand_path("path/to/a_spec.rb") => [37]}})
+      end
+    end
+
+    context "with full_description set" do
+      it "overrides filters" do
+        config.filter_run :focused => true
+        config.full_description = "foo"
+        expect(inclusion_filter).not_to have_key(:focused)
+      end
+
+      it 'is possible to access the full description regular expression' do
+        config.full_description = "foo"
+        expect(config.full_description).to eq(/foo/)
+      end
+    end
+
+    context "without full_description having been set" do
+      it 'returns nil from #full_description' do
+        expect(config.full_description).to eq nil
+      end
+    end
+
+    context "with line number" do
+      it "assigns the file and line number as a location filter" do
+        assign_files_or_directories_to_run "path/to/a_spec.rb:37"
+        expect(inclusion_filter).to eq({:locations => {File.expand_path("path/to/a_spec.rb") => [37]}})
+      end
+
+      it "assigns multiple files with line numbers as location filters" do
+        assign_files_or_directories_to_run "path/to/a_spec.rb:37", "other_spec.rb:44"
+        expect(inclusion_filter).to eq({:locations => {File.expand_path("path/to/a_spec.rb") => [37],
+                                                File.expand_path("other_spec.rb") => [44]}})
+      end
+
+      it "assigns files with multiple line numbers as location filters" do
+        assign_files_or_directories_to_run "path/to/a_spec.rb:37", "path/to/a_spec.rb:44"
+        expect(inclusion_filter).to eq({:locations => {File.expand_path("path/to/a_spec.rb") => [37, 44]}})
+      end
+    end
+
+    context "with multiple line numbers" do
+      it "assigns the file and line numbers as a location filter" do
+        assign_files_or_directories_to_run "path/to/a_spec.rb:1:3:5:7"
+        expect(inclusion_filter).to eq({:locations => {File.expand_path("path/to/a_spec.rb") => [1,3,5,7]}})
+      end
+    end
+
+    it "assigns the example name as the filter on description" do
+      config.full_description = "foo"
+      expect(inclusion_filter).to eq({:full_description => /foo/})
+    end
+
+    it "assigns the example names as the filter on description if description is an array" do
+      config.full_description = [ "foo", "bar" ]
+      expect(inclusion_filter).to eq({:full_description => Regexp.union(/foo/, /bar/)})
+    end
+
+    it 'is possible to access the full description regular expression' do
+      config.full_description = "foo","bar"
+      expect(config.full_description).to eq Regexp.union(/foo/,/bar/)
+    end
+
+    describe "#default_path" do
+      it 'defaults to "spec"' do
+        expect(config.default_path).to eq('spec')
+      end
+    end
+
+    describe "#include" do
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :include, Enumerable
+
+      module InstanceLevelMethods
+        def you_call_this_a_blt?
+          "egad man, where's the mayo?!?!?"
+        end
+      end
+
+      it_behaves_like "metadata hash builder" do
+        def metadata_hash(*args)
+          config.include(InstanceLevelMethods, *args)
+          config.instance_variable_get(:@include_modules).items_and_filters.last.last
+        end
+      end
+
+      context "with no filter" do
+        it "includes the given module into each example group" do
+          RSpec.configure do |c|
+            c.include(InstanceLevelMethods)
+          end
+
+          group = RSpec.describe('does like, stuff and junk', :magic_key => :include) { }
+          expect(group).not_to respond_to(:you_call_this_a_blt?)
+          expect(group.new.you_call_this_a_blt?).to eq("egad man, where's the mayo?!?!?")
+        end
+      end
+
+      context "with a filter" do
+        it "includes the given module into each matching example group" do
+          RSpec.configure do |c|
+            c.include(InstanceLevelMethods, :magic_key => :include)
+          end
+
+          group = RSpec.describe('does like, stuff and junk', :magic_key => :include) { }
+          expect(group).not_to respond_to(:you_call_this_a_blt?)
+          expect(group.new.you_call_this_a_blt?).to eq("egad man, where's the mayo?!?!?")
+        end
+
+        it "includes the given module into the singleton class of matching examples" do
+          RSpec.configure do |c|
+            c.include(InstanceLevelMethods, :magic_key => :include)
+          end
+
+          value = ex1 = ex2 = nil
+
+          RSpec.describe("Group") do
+            ex1 = example("ex", :magic_key => :include) do
+              value = you_call_this_a_blt?
+            end
+
+            ex2 = example("ex") { you_call_this_a_blt? }
+          end.run
+
+          expect(ex1.execution_result.exception).to be_nil
+          expect(value).to match(/egad/)
+          expect(ex2.execution_result.exception).to be_a(NameError)
+        end
+
+        it "ensures that `before` hooks have access to the module methods, even when only included in the singleton class of one example" do
+          RSpec.configure do |c|
+            c.include(Module.new { def which_mod; :mod_1; end }, :mod_1)
+            c.include(Module.new { def which_mod; :mod_2; end }, :mod_2)
+          end
+
+          ex1_value = ex2_value = ex3 = nil
+
+          RSpec.describe("group") do
+            before { @value = which_mod }
+            example("ex", :mod_1) { ex1_value = @value }
+            example("ex", :mod_2) { ex2_value = @value }
+            ex3 = example("ex") { }
+          end.run
+
+          expect(ex1_value).to eq(:mod_1)
+          expect(ex2_value).to eq(:mod_2)
+          expect(ex3.execution_result.exception).to be_a(NameError)
+        end
+
+        it "does not include the module in an example's singleton class when it has already been included in the group" do
+          mod = Module.new do
+            def self.inclusions
+              @inclusions ||= []
+            end
+
+            def self.included(klass)
+              inclusions << klass
+            end
+          end
+
+          RSpec.configure do |c|
+            c.include mod, :magic_key
+          end
+
+          group = RSpec.describe("Group", :magic_key) do
+            example("ex", :magic_key) { }
+          end
+
+          group.run
+          expect(mod.inclusions).to eq([group])
+        end
+      end
+    end
+
+    describe "#extend" do
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :extend, Enumerable
+
+      module ThatThingISentYou
+        def that_thing
+        end
+      end
+
+      it_behaves_like "metadata hash builder" do
+        def metadata_hash(*args)
+          config.extend(ThatThingISentYou, *args)
+          config.instance_variable_get(:@extend_modules).items_and_filters.last.last
+        end
+      end
+
+      it "extends the given module into each matching example group" do
+        RSpec.configure do |c|
+          c.extend(ThatThingISentYou, :magic_key => :extend)
+        end
+
+        group = RSpec.describe(ThatThingISentYou, :magic_key => :extend) { }
+        expect(group).to respond_to(:that_thing)
+      end
+
+    end
+
+    describe "#prepend", :if => RSpec::Support::RubyFeatures.module_prepends_supported? do
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :prepend, Enumerable
+
+      module SomeRandomMod
+        def foo
+          "foobar"
+        end
+      end
+
+      it_behaves_like "metadata hash builder" do
+        def metadata_hash(*args)
+          config.prepend(SomeRandomMod, *args)
+          config.instance_variable_get(:@prepend_modules).items_and_filters.last.last
+        end
+      end
+
+      context "with no filter" do
+        it "prepends the given module into each example group" do
+          RSpec.configure do |c|
+            c.prepend(SomeRandomMod)
+          end
+
+          group = RSpec.describe('yo') { }
+          expect(group.new.foo).to eq("foobar")
+        end
+      end
+
+      context "with a filter" do
+        it "prepends the given module into each matching example group" do
+          RSpec.configure do |c|
+            c.prepend(SomeRandomMod, :magic_key => :include)
+          end
+
+          group = RSpec.describe('yo', :magic_key => :include) { }
+          expect(group.new.foo).to eq("foobar")
+        end
+      end
+
+    end
+
+    describe "#run_all_when_everything_filtered?" do
+
+      it "defaults to false" do
+        expect(config.run_all_when_everything_filtered?).to be_falsey
+      end
+
+      it "can be queried with question method" do
+        config.run_all_when_everything_filtered = true
+        expect(config.run_all_when_everything_filtered?).to be_truthy
+      end
+    end
+
+    describe "#color=" do
+      context "given true" do
+        before { config.color = true }
+
+        context "with config.tty? and output.tty?" do
+          it "sets color_enabled?" do
+            output = StringIO.new
+            config.output_stream = output
+
+            config.tty = true
+            allow(config.output_stream).to receive_messages :tty? => true
+
+            expect(config.color_enabled?).to be_truthy
+            expect(config.color_enabled?(output)).to be_truthy
+          end
+        end
+
+        context "with config.tty? and !output.tty?" do
+          it "sets color_enabled?" do
+            output = StringIO.new
+            config.output_stream = output
+
+            config.tty = true
+            allow(config.output_stream).to receive_messages :tty? => false
+
+            expect(config.color_enabled?).to be_truthy
+            expect(config.color_enabled?(output)).to be_truthy
+          end
+        end
+
+        context "with config.tty? and !output.tty?" do
+          it "does not set color_enabled?" do
+            output = StringIO.new
+            config.output_stream = output
+
+            config.tty = false
+            allow(config.output_stream).to receive_messages :tty? => true
+
+            expect(config.color_enabled?).to be_truthy
+            expect(config.color_enabled?(output)).to be_truthy
+          end
+        end
+
+        context "with !config.tty? and !output.tty?" do
+          it "does not set color_enabled?" do
+            output = StringIO.new
+            config.output_stream = output
+
+            config.tty = false
+            allow(config.output_stream).to receive_messages :tty? => false
+
+            expect(config.color_enabled?).to be_falsey
+            expect(config.color_enabled?(output)).to be_falsey
+          end
+        end
+      end
+
+      context "on windows" do
+        before do
+          @original_host  = RbConfig::CONFIG['host_os']
+          RbConfig::CONFIG['host_os'] = 'mingw'
+          allow(config).to receive(:require)
+        end
+
+        after do
+          RbConfig::CONFIG['host_os'] = @original_host
+        end
+
+        context "with ANSICON available" do
+          around(:each) { |e| with_env_vars('ANSICON' => 'ANSICON', &e) }
+
+          it "enables colors" do
+            config.output_stream = StringIO.new
+            allow(config.output_stream).to receive_messages :tty? => true
+            config.color = true
+            expect(config.color).to be_truthy
+          end
+
+          it "leaves output stream intact" do
+            config.output_stream = $stdout
+            allow(config).to receive(:require) do |what|
+              config.output_stream = 'foo' if what =~ /Win32/
+            end
+            config.color = true
+            expect(config.output_stream).to eq($stdout)
+          end
+        end
+
+        context "with ANSICON NOT available" do
+          around { |e| without_env_vars('ANSICON', &e) }
+
+          before do
+            allow_warning
+          end
+
+          it "warns to install ANSICON" do
+            allow(config).to receive(:require) { raise LoadError }
+            expect_warning_with_call_site(__FILE__, __LINE__ + 1, /You must use ANSICON/)
+            config.color = true
+          end
+
+          it "sets color to false" do
+            allow(config).to receive(:require) { raise LoadError }
+            config.color = true
+            expect(config.color).to be_falsey
+          end
+        end
+      end
+
+      it "prefers incoming cli_args" do
+        config.output_stream = StringIO.new
+        allow(config.output_stream).to receive_messages :tty? => true
+        config.force :color => true
+        config.color = false
+        expect(config.color).to be_truthy
+      end
+    end
+
+    %w[formatter= add_formatter].each do |config_method|
+      describe "##{config_method}" do
+        it "delegates to formatters#add" do
+          expect(config.formatter_loader).to receive(:add).with('these','options')
+          config.send(config_method,'these','options')
+        end
+      end
+    end
+
+    describe "#formatters" do
+      it "returns a dup of the formatter_loader formatters" do
+        config.add_formatter 'doc'
+        config.formatters.clear
+        expect(config.formatters).to_not eq []
+      end
+    end
+
+    describe "#default_formatter" do
+      it 'defaults to `progress`' do
+        expect(config.default_formatter).to eq('progress')
+      end
+
+      it 'remembers changes' do
+        config.default_formatter = 'doc'
+        expect(config.default_formatter).to eq('doc')
+      end
+
+      context 'when another formatter has been set' do
+        it 'does not get used' do
+          config.default_formatter = 'doc'
+          config.add_formatter 'progress'
+
+          expect(used_formatters).to include(an_instance_of Formatters::ProgressFormatter)
+          expect(used_formatters).not_to include(an_instance_of Formatters::DocumentationFormatter)
+        end
+      end
+
+      context 'when no other formatter has been set' do
+        it 'gets used' do
+          config.default_formatter = 'doc'
+
+          expect(used_formatters).not_to include(an_instance_of Formatters::ProgressFormatter)
+          expect(used_formatters).to include(an_instance_of Formatters::DocumentationFormatter)
+        end
+      end
+
+      context 'using a legacy formatter as default' do
+        # Generating warnings during formatter initialisation triggers the
+        # ProxyReporter code path.
+        it 'remembers changes' do
+          legacy_formatter = Class.new
+
+          configuration = RSpec.configuration
+          configuration.default_formatter = legacy_formatter
+          configuration.reporter
+          expect(configuration.default_formatter).to eq(legacy_formatter)
+        end
+      end
+
+      def used_formatters
+        config.reporter # to force freezing of formatters
+        config.formatters
+      end
+    end
+
+    describe "#filter_run_including" do
+      it_behaves_like "metadata hash builder" do
+        def metadata_hash(*args)
+          config.filter_run_including(*args)
+          config.inclusion_filter.rules
+        end
+      end
+
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :filter_run_including
+
+      it "sets the filter with a hash" do
+        config.filter_run_including :foo => true
+        expect(inclusion_filter).to eq( {:foo => true} )
+      end
+
+      it "sets the filter with a symbol" do
+        config.filter_run_including :foo
+        expect(inclusion_filter).to eq( {:foo => true} )
+      end
+
+      it "merges with existing filters" do
+        config.filter_run_including :foo => true
+        config.filter_run_including :bar => false
+        expect(inclusion_filter).to eq( {:foo => true, :bar => false} )
+      end
+    end
+
+    describe "#filter_run_excluding" do
+      it_behaves_like "metadata hash builder" do
+        def metadata_hash(*args)
+          config.filter_run_excluding(*args)
+          config.exclusion_filter.rules
+        end
+      end
+
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :filter_run_excluding
+
+      it "sets the filter" do
+        config.filter_run_excluding :foo => true
+        expect(exclusion_filter).to eq( {:foo => true} )
+      end
+
+      it "sets the filter using a symbol" do
+        config.filter_run_excluding :foo
+        expect(exclusion_filter).to eq( {:foo => true} )
+      end
+
+      it "merges with existing filters" do
+        config.filter_run_excluding :foo => true
+        config.filter_run_excluding :bar => false
+        expect(exclusion_filter).to eq( {:foo => true, :bar => false} )
+      end
+    end
+
+    shared_examples_for "a spec filter" do |type|
+      describe "##{type}" do
+        it "returns {} even if set to nil" do
+          config.send("#{type}=", nil)
+          expect(send(type)).to eq({})
+        end
+      end
+
+      describe "##{type}=" do
+        it "treats symbols as hash keys with true values when told to" do
+          config.send("#{type}=", :foo)
+          expect(send(type)).to eq( {:foo => true} )
+        end
+
+        it "overrides any #{type} set on the command line or in configuration files" do
+          config.force(type => { :foo => :bar })
+          config.send("#{type}=", {:want => :this})
+          expect(send(type)).to eq( {:want => :this} )
+        end
+
+        include_examples "warning of deprecated `:example_group` during filtering configuration", :"#{type}="
+      end
+    end
+    it_behaves_like "a spec filter", :inclusion_filter
+    it_behaves_like "a spec filter", :exclusion_filter
+
+    describe "#treat_symbols_as_metadata_keys_with_true_values=" do
+      it 'is deprecated' do
+        expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
+        config.treat_symbols_as_metadata_keys_with_true_values = true
+      end
+    end
+
+    describe "#full_backtrace=" do
+      it "doesn't impact other instances of config" do
+        config_1 = Configuration.new
+        config_2 = Configuration.new
+
+        config_1.full_backtrace = true
+        expect(config_2.full_backtrace?).to be_falsey
+      end
+    end
+
+    describe "#backtrace_exclusion_patterns=" do
+      it "actually receives the new filter values" do
+        config.backtrace_exclusion_patterns = [/.*/]
+        expect(config.backtrace_formatter.exclude? "this").to be_truthy
+      end
+    end
+
+    describe 'full_backtrace' do
+      it 'returns true when backtrace patterns is empty' do
+        config.backtrace_exclusion_patterns = []
+        expect(config.full_backtrace?).to eq true
+      end
+
+      it 'returns false when backtrace patterns isnt empty' do
+        config.backtrace_exclusion_patterns = [:lib]
+        expect(config.full_backtrace?).to eq false
+      end
+    end
+
+    describe "#backtrace_exclusion_patterns" do
+      it "can be appended to" do
+        config.backtrace_exclusion_patterns << /.*/
+        expect(config.backtrace_formatter.exclude? "this").to be_truthy
+      end
+    end
+
+    describe "#filter_gems_from_backtrace" do
+      def exclude?(line)
+        config.backtrace_formatter.exclude?(line)
+      end
+
+      it 'filters the named gems from the backtrace' do
+        line_1 = "/Users/myron/.gem/ruby/2.1.1/gems/foo-1.6.3.1/foo.rb:13"
+        line_2 = "/Users/myron/.gem/ruby/2.1.1/gems/bar-1.6.3.1/bar.rb:13"
+
+        expect {
+          config.filter_gems_from_backtrace "foo", "bar"
+        }.to change { exclude?(line_1) }.from(false).to(true).
+         and change { exclude?(line_2) }.from(false).to(true)
+      end
+    end
+
+    describe "#libs=" do
+      it "adds directories to the LOAD_PATH" do
+        expect($LOAD_PATH).to receive(:unshift).with("a/dir")
+        config.libs = ["a/dir"]
+      end
+    end
+
+    describe "libs" do
+      it 'records paths added to the load path' do
+        config.libs = ["a/dir"]
+        expect(config.libs).to eq ["a/dir"]
+      end
+    end
+
+    describe "#define_derived_metadata" do
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :define_derived_metadata
+
+      it 'allows the provided block to mutate example group metadata' do
+        RSpec.configuration.define_derived_metadata do |metadata|
+          metadata[:reverse_description] = metadata[:description].reverse
+        end
+
+        group = RSpec.describe("My group")
+        expect(group.metadata).to include(:description => "My group", :reverse_description => "puorg yM")
+      end
+
+      it 'allows the provided block to mutate example metadata' do
+        RSpec.configuration.define_derived_metadata do |metadata|
+          metadata[:reverse_description] = metadata[:description].reverse
+        end
+
+        ex = RSpec.describe("My group").example("foo")
+        expect(ex.metadata).to include(:description => "foo", :reverse_description => "oof")
+      end
+
+      it 'allows multiple configured blocks to be applied, in order of definition' do
+        RSpec.configure do |c|
+          c.define_derived_metadata { |m| m[:b1_desc] = m[:description] + " (block 1)" }
+          c.define_derived_metadata { |m| m[:b2_desc] = m[:b1_desc]     + " (block 2)" }
+        end
+
+        group = RSpec.describe("bar")
+        expect(group.metadata).to include(:b1_desc => "bar (block 1)", :b2_desc => "bar (block 1) (block 2)")
+      end
+
+      it "derives metadata before the group or example blocks are eval'd so their logic can depend on the derived metadata" do
+        RSpec.configure do |c|
+          c.define_derived_metadata(:foo) do |metadata|
+            metadata[:bar] = "bar"
+          end
+        end
+
+        group_bar_value = example_bar_value = nil
+
+        RSpec.describe "Group", :foo do
+          group_bar_value = self.metadata[:bar]
+          example_bar_value = example("ex", :foo).metadata[:bar]
+        end
+
+        expect(group_bar_value).to eq("bar")
+        expect(example_bar_value).to eq("bar")
+      end
+
+      context "when passed a metadata filter" do
+        it 'only applies to the groups and examples that match that filter' do
+          RSpec.configure do |c|
+            c.define_derived_metadata(:apply => true) do |metadata|
+              metadata[:reverse_description] = metadata[:description].reverse
+            end
+          end
+
+          g1 = RSpec.describe("G1", :apply)
+          g2 = RSpec.describe("G2")
+          e1 = g1.example("E1")
+          e2 = g2.example("E2", :apply)
+          e3 = g2.example("E3")
+
+          expect(g1.metadata).to include(:reverse_description => "1G")
+          expect(g2.metadata).not_to include(:reverse_description)
+
+          expect(e1.metadata).to include(:reverse_description => "1E")
+          expect(e2.metadata).to include(:reverse_description => "2E")
+          expect(e3.metadata).not_to include(:reverse_description)
+        end
+
+        it 'applies if any of multiple filters apply (to align with module inclusion semantics)' do
+          RSpec.configure do |c|
+            c.define_derived_metadata(:a => 1, :b => 2) do |metadata|
+              metadata[:reverse_description] = metadata[:description].reverse
+            end
+          end
+
+          g1 = RSpec.describe("G1", :a => 1)
+          g2 = RSpec.describe("G2", :b => 2)
+          g3 = RSpec.describe("G3", :c => 3)
+
+          expect(g1.metadata).to include(:reverse_description => "1G")
+          expect(g2.metadata).to include(:reverse_description => "2G")
+          expect(g3.metadata).not_to include(:reverse_description)
+        end
+
+        it 'allows a metadata filter to be passed as a raw symbol' do
+          RSpec.configure do |c|
+            c.define_derived_metadata(:apply) do |metadata|
+              metadata[:reverse_description] = metadata[:description].reverse
+            end
+          end
+
+          g1 = RSpec.describe("G1", :apply)
+          g2 = RSpec.describe("G2")
+
+          expect(g1.metadata).to include(:reverse_description => "1G")
+          expect(g2.metadata).not_to include(:reverse_description)
+        end
+      end
+    end
+
+    describe "#add_setting" do
+      describe "with no modifiers" do
+        context "with no additional options" do
+          before do
+            config.add_setting :custom_option
+          end
+
+          it "defaults to nil" do
+            expect(config.custom_option).to be_nil
+          end
+
+          it "adds a predicate" do
+            expect(config.custom_option?).to be_falsey
+          end
+
+          it "can be overridden" do
+            config.custom_option = "a value"
+            expect(config.custom_option).to eq("a value")
+          end
+        end
+
+        context "with :default => 'a value'" do
+          before do
+            config.add_setting :custom_option, :default => 'a value'
+          end
+
+          it "defaults to 'a value'" do
+            expect(config.custom_option).to eq("a value")
+          end
+
+          it "returns true for the predicate" do
+            expect(config.custom_option?).to be_truthy
+          end
+
+          it "can be overridden with a truthy value" do
+            config.custom_option = "a new value"
+            expect(config.custom_option).to eq("a new value")
+          end
+
+          it "can be overridden with nil" do
+            config.custom_option = nil
+            expect(config.custom_option).to eq(nil)
+          end
+
+          it "can be overridden with false" do
+            config.custom_option = false
+            expect(config.custom_option).to eq(false)
+          end
+        end
+      end
+
+      context "with :alias_with => " do
+        before do
+          config.add_setting :custom_option, :alias_with => :another_custom_option
+        end
+
+        it "delegates the getter to the other option" do
+          config.another_custom_option = "this value"
+          expect(config.custom_option).to eq("this value")
+        end
+
+        it "delegates the setter to the other option" do
+          config.custom_option = "this value"
+          expect(config.another_custom_option).to eq("this value")
+        end
+
+        it "delegates the predicate to the other option" do
+          config.custom_option = true
+          expect(config.another_custom_option?).to be_truthy
+        end
+      end
+    end
+
+    describe "#configure_group" do
+      it "extends with 'extend'" do
+        mod = Module.new
+        group = RSpec.describe("group", :foo => :bar)
+
+        config.extend(mod, :foo => :bar)
+        config.configure_group(group)
+        expect(group).to be_a(mod)
+      end
+
+      it "includes with 'include'" do
+        mod = Module.new
+        group = RSpec.describe("group", :foo => :bar)
+
+        config.include(mod, :foo => :bar)
+        config.configure_group(group)
+        expect(group.included_modules).to include(mod)
+      end
+
+      it "requires only one matching filter" do
+        mod = Module.new
+        group = RSpec.describe("group", :foo => :bar)
+
+        config.include(mod, :foo => :bar, :baz => :bam)
+        config.configure_group(group)
+        expect(group.included_modules).to include(mod)
+      end
+
+      module IncludeExtendOrPrependMeOnce
+        def self.included(host)
+          raise "included again" if host.instance_methods.include?(:foobar)
+          host.class_exec { def foobar; end }
+        end
+
+        def self.extended(host)
+          raise "extended again" if host.respond_to?(:foobar)
+          def host.foobar; end
+        end
+
+        def self.prepended(host)
+          raise "prepended again" if host.instance_methods.include?(:barbaz)
+          host.class_exec { def barbaz; end }
+        end
+      end
+
+      it "doesn't include a module when already included in ancestor" do
+        config.include(IncludeExtendOrPrependMeOnce, :foo => :bar)
+
+        group = RSpec.describe("group", :foo => :bar)
+        child = group.describe("child")
+
+        config.configure_group(group)
+        config.configure_group(child)
+      end
+
+      it "doesn't extend when ancestor is already extended with same module" do
+        config.extend(IncludeExtendOrPrependMeOnce, :foo => :bar)
+
+        group = RSpec.describe("group", :foo => :bar)
+        child = group.describe("child")
+
+        config.configure_group(group)
+        config.configure_group(child)
+      end
+
+      it "doesn't prepend a module when already present in ancestor chain",
+        :if => RSpec::Support::RubyFeatures.module_prepends_supported? do
+        config.prepend(IncludeExtendOrPrependMeOnce, :foo => :bar)
+
+        group = RSpec.describe("group", :foo => :bar)
+        child = group.describe("child")
+
+        config.configure_group(group)
+        config.configure_group(child)
+      end
+    end
+
+    describe "#alias_example_group_to" do
+      after do
+        RSpec::Core::DSL.example_group_aliases.delete(:my_group_method)
+
+        RSpec.module_exec do
+          class << self
+            undef :my_group_method if method_defined? :my_group_method
+          end
+        end
+
+        RSpec::Core::ExampleGroup.module_exec do
+          class << self
+            undef :my_group_method if method_defined? :my_group_method
+          end
+        end
+
+        Module.class_exec do
+          undef :my_group_method if method_defined? :my_group_method
+        end
+      end
+
+      it_behaves_like "metadata hash builder" do
+        def metadata_hash(*args)
+          config.alias_example_group_to :my_group_method, *args
+          group = ExampleGroup.my_group_method("a group")
+          group.metadata
+        end
+      end
+
+      it 'overrides existing definitions of the aliased method name without issueing warnings' do
+        config.expose_dsl_globally = true
+
+        class << ExampleGroup
+          def my_group_method; :original; end
+        end
+
+        Module.class_exec do
+          def my_group_method; :original; end
+        end
+
+        config.alias_example_group_to :my_group_method
+
+        expect(ExampleGroup.my_group_method).to be < ExampleGroup
+        expect(Module.new.my_group_method).to be < ExampleGroup
+      end
+
+      it "allows adding additional metadata" do
+        config.alias_example_group_to :my_group_method, { :some => "thing" }
+        group = ExampleGroup.my_group_method("a group", :another => "thing")
+        expect(group.metadata).to include(:some => "thing", :another => "thing")
+      end
+
+      it "passes `nil` as the description arg when no args are given" do
+        config.alias_example_group_to :my_group_method, { :some => "thing" }
+        group = ExampleGroup.my_group_method
+
+        expect(group.metadata).to include(
+          :description_args => [nil],
+          :description => "",
+          :some => "thing"
+        )
+      end
+
+      context 'when the aliased method is used' do
+        it_behaves_like "metadata hash builder" do
+          def metadata_hash(*args)
+            config.alias_example_group_to :my_group_method
+            group = ExampleGroup.my_group_method("a group", *args)
+            group.metadata
+          end
+        end
+      end
+    end
+
+    describe "#alias_example_to" do
+      it_behaves_like "metadata hash builder" do
+        after do
+          RSpec::Core::ExampleGroup.module_exec do
+            class << self
+              undef :my_example_method if method_defined? :my_example_method
+            end
+          end
+        end
+        def metadata_hash(*args)
+          config.alias_example_to :my_example_method, *args
+          group = RSpec.describe("group")
+          example = group.my_example_method("description")
+          example.metadata
+        end
+      end
+    end
+
+    describe "#reset" do
+      it "clears the reporter" do
+        expect(config.reporter).not_to be_nil
+        config.reset
+        expect(config.instance_variable_get("@reporter")).to be_nil
+      end
+
+      it "clears the formatters" do
+        config.add_formatter "doc"
+        config.reset
+        expect(config.formatters).to be_empty
+      end
+    end
+
+    describe "#force" do
+      context "for ordering options" do
+        let(:list) { [1, 2, 3, 4] }
+        let(:ordering_strategy) { config.ordering_registry.fetch(:global) }
+        let(:rng) { RSpec::Core::RandomNumberGenerator.new config.seed }
+        let(:shuffled) { Ordering::Random.new(config).shuffle list, rng }
+
+        specify "CLI `--order defined` takes precedence over `config.order = rand`" do
+          config.force :order => "defined"
+          config.order = "rand"
+
+          expect(ordering_strategy.order(list)).to eq([1, 2, 3, 4])
+        end
+
+        specify "CLI `--order rand:37` takes precedence over `config.order = defined`" do
+          config.force :order => "rand:37"
+          config.order = "defined"
+
+          expect(ordering_strategy.order(list)).to eq(shuffled)
+        end
+
+        specify "CLI `--seed 37` forces order and seed" do
+          config.force :seed => 37
+          config.order = "defined"
+          config.seed  = 145
+
+          expect(ordering_strategy.order(list)).to eq(shuffled)
+          expect(config.seed).to eq(37)
+        end
+
+        specify "CLI `--order defined` takes precedence over `config.register_ordering(:global)`" do
+          config.force :order => "defined"
+          config.register_ordering(:global, &:reverse)
+          expect(ordering_strategy.order(list)).to eq([1, 2, 3, 4])
+        end
+      end
+
+      it "forces 'false' value" do
+        config.add_setting :custom_option
+        config.custom_option = true
+        expect(config.custom_option?).to be_truthy
+        config.force :custom_option => false
+        expect(config.custom_option?).to be_falsey
+        config.custom_option = true
+        expect(config.custom_option?).to be_falsey
+      end
+    end
+
+    describe '#seed' do
+      it 'returns the seed as an int' do
+        config.seed = '123'
+        expect(config.seed).to eq(123)
+      end
+    end
+
+    describe "#seed_used?" do
+      def use_seed_on(registry)
+        registry.fetch(:random).order([1, 2])
+      end
+
+      it 'returns false if neither ordering registry used the seed' do
+        expect(config.seed_used?).to be false
+      end
+
+      it 'returns true if the ordering registry used the seed' do
+        use_seed_on(config.ordering_registry)
+        expect(config.seed_used?).to be true
+      end
+    end
+
+    describe '#order=' do
+      context 'given "random"' do
+        before do
+          config.seed = 7654
+          config.order = 'random'
+        end
+
+        it 'does not change the seed' do
+          expect(config.seed).to eq(7654)
+        end
+
+        it 'sets up random ordering' do
+          allow(RSpec).to receive_messages(:configuration => config)
+          global_ordering = config.ordering_registry.fetch(:global)
+          expect(global_ordering).to be_an_instance_of(Ordering::Random)
+        end
+      end
+
+      context 'given "random:123"' do
+        before { config.order = 'random:123' }
+
+        it 'sets seed to 123' do
+          expect(config.seed).to eq(123)
+        end
+
+        it 'sets up random ordering' do
+          allow(RSpec).to receive_messages(:configuration => config)
+          global_ordering = config.ordering_registry.fetch(:global)
+          expect(global_ordering).to be_an_instance_of(Ordering::Random)
+        end
+      end
+
+      context 'given "defined"' do
+        before do
+          config.order = 'rand:123'
+          config.order = 'defined'
+        end
+
+        it "does not change the seed" do
+          expect(config.seed).to eq(123)
+        end
+
+        it 'clears the random ordering' do
+          allow(RSpec).to receive_messages(:configuration => config)
+          list = [1, 2, 3, 4]
+          ordering_strategy = config.ordering_registry.fetch(:global)
+          expect(ordering_strategy.order(list)).to eq([1, 2, 3, 4])
+        end
+      end
+    end
+
+    describe "#register_ordering" do
+      def register_reverse_ordering
+        config.register_ordering(:reverse, &:reverse)
+      end
+
+      it 'stores the ordering for later use' do
+        register_reverse_ordering
+
+        list = [1, 2, 3]
+        strategy = config.ordering_registry.fetch(:reverse)
+        expect(strategy).to be_a(Ordering::Custom)
+        expect(strategy.order(list)).to eq([3, 2, 1])
+      end
+
+      it 'can register an ordering object' do
+        strategy = Object.new
+        def strategy.order(list)
+          list.reverse
+        end
+
+        config.register_ordering(:reverse, strategy)
+        list = [1, 2, 3]
+        fetched = config.ordering_registry.fetch(:reverse)
+        expect(fetched).to be(strategy)
+        expect(fetched.order(list)).to eq([3, 2, 1])
+      end
+    end
+
+    describe '#warnings' do
+      around do |example|
+        original_setting = $VERBOSE
+        example.run
+        $VERBOSE = original_setting
+      end
+
+      it "sets verbose to true when true" do
+        config.warnings = true
+        expect($VERBOSE).to eq true
+      end
+
+      it "sets verbose to false when true" do
+        config.warnings = false
+        expect($VERBOSE).to eq false
+      end
+
+      it 'returns the verbosity setting' do
+        config.warnings = true
+        expect(config.warnings?).to eq true
+
+        config.warnings = false
+        expect(config.warnings?).to eq false
+      end
+
+      it 'is loaded from config by #force' do
+        config.force :warnings => true
+        expect($VERBOSE).to eq true
+      end
+    end
+
+    describe "#raise_errors_for_deprecations!" do
+      it 'causes deprecations to raise errors rather than printing to the deprecation stream' do
+        config.deprecation_stream = stream = StringIO.new
+        config.raise_errors_for_deprecations!
+
+        expect {
+          config.reporter.deprecation(:deprecated => "foo", :call_site => "foo.rb:1")
+        }.to raise_error(RSpec::Core::DeprecationError, /foo is deprecated/)
+
+        expect(stream.string).to eq("")
+      end
+    end
+
+    describe "#expose_current_running_example_as" do
+      before { stub_const(Configuration::ExposeCurrentExample.name, Module.new) }
+
+      it 'exposes the current example via the named method' do
+        RSpec.configuration.expose_current_running_example_as :the_example
+        RSpec.configuration.expose_current_running_example_as :another_example_helper
+
+        value_1 = value_2 = nil
+
+        RSpec.describe "Group" do
+          it "works" do
+            value_1 = the_example
+            value_2 = another_example_helper
+          end
+        end.run
+
+        expect(value_1).to be_an(RSpec::Core::Example)
+        expect(value_1.description).to eq("works")
+        expect(value_2).to be(value_1)
+      end
+    end
+
+    describe '#disable_monkey_patching!' do
+      let!(:config) { RSpec.configuration }
+      let!(:expectations) { RSpec::Expectations }
+      let!(:mocks) { RSpec::Mocks }
+
+      def in_fully_monkey_patched_rspec_environment
+        in_sub_process do
+          config.expose_dsl_globally = true
+          mocks.configuration.syntax = [:expect, :should]
+          mocks.configuration.patch_marshal_to_support_partial_doubles = true
+          expectations.configuration.syntax = [:expect, :should]
+
+          yield
+        end
+      end
+
+      it 'stops exposing the DSL methods globally' do
+        in_fully_monkey_patched_rspec_environment do
+          mod = Module.new
+          expect {
+            config.disable_monkey_patching!
+          }.to change { mod.respond_to?(:describe) }.from(true).to(false)
+        end
+      end
+
+      it 'stops using should syntax for expectations' do
+        in_fully_monkey_patched_rspec_environment do
+          obj = Object.new
+          config.expect_with :rspec
+          expect {
+            config.disable_monkey_patching!
+          }.to change { obj.respond_to?(:should) }.from(true).to(false)
+        end
+      end
+
+      it 'stops using should syntax for mocks' do
+        in_fully_monkey_patched_rspec_environment do
+          obj = Object.new
+          config.mock_with :rspec
+          expect {
+            config.disable_monkey_patching!
+          }.to change { obj.respond_to?(:should_receive) }.from(true).to(false)
+        end
+      end
+
+      it 'stops patching of Marshal' do
+        in_fully_monkey_patched_rspec_environment do
+          expect {
+            config.disable_monkey_patching!
+          }.to change { Marshal.respond_to?(:dump_with_rspec_mocks) }.from(true).to(false)
+        end
+      end
+
+      context 'when user did not configure mock framework' do
+        def emulate_not_configured_mock_framework
+          in_fully_monkey_patched_rspec_environment do
+            allow(config).to receive(:rspec_mocks_loaded?).and_return(false, true)
+            config.instance_variable_set :@mock_framework, nil
+            ExampleGroup.send :remove_class_variable, :@@example_groups_configured
+
+            yield
+          end
+        end
+
+        it 'disables monkey patching after example groups being configured' do
+          emulate_not_configured_mock_framework do
+            obj = Object.new
+            config.disable_monkey_patching!
+
+            expect {
+              ExampleGroup.ensure_example_groups_are_configured
+            }.to change { obj.respond_to?(:should_receive) }.from(true).to(false)
+          end
+        end
+      end
+
+      context 'when user did not configure expectation framework' do
+        def emulate_not_configured_expectation_framework
+          in_fully_monkey_patched_rspec_environment do
+            allow(config).to receive(:rspec_expectations_loaded?).and_return(false, true)
+            config.instance_variable_set :@expectation_frameworks, []
+            ExampleGroup.send :remove_class_variable, :@@example_groups_configured
+
+            yield
+          end
+        end
+
+        it 'disables monkey patching after example groups being configured' do
+          emulate_not_configured_expectation_framework do
+            obj = Object.new
+            config.disable_monkey_patching!
+
+            expect {
+              ExampleGroup.ensure_example_groups_are_configured
+            }.to change { obj.respond_to?(:should) }.from(true).to(false)
+          end
+        end
+      end
+    end
+
+    describe 'recording spec start time (for measuring load)' do
+      it 'returns a time' do
+        expect(config.start_time).to be_an_instance_of ::Time
+      end
+
+      it 'is configurable' do
+        config.start_time = 42
+        expect(config.start_time).to eq 42
+      end
+    end
+
+    describe "hooks" do
+      include_examples "warning of deprecated `:example_group` during filtering configuration", :before, :each
+    end
+
+    # assigns files_or_directories_to_run and triggers post-processing
+    # via `files_to_run`.
+    def assign_files_or_directories_to_run(*value)
+      config.files_or_directories_to_run = value
+      config.files_to_run
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/drb_spec.rb b/rspec-core/spec/rspec/core/drb_spec.rb
new file mode 100644
index 0000000..505294d
--- /dev/null
+++ b/rspec-core/spec/rspec/core/drb_spec.rb
@@ -0,0 +1,277 @@
+require 'rspec/core/drb'
+
+RSpec.describe RSpec::Core::DRbRunner, :isolated_directory => true, :isolated_home => true, :type => :drb, :unless => RUBY_PLATFORM == 'java' do
+  let(:config) { RSpec::Core::Configuration.new }
+  let(:out)    { StringIO.new }
+  let(:err)    { StringIO.new }
+
+  include_context "spec files"
+
+  def runner(*args)
+    RSpec::Core::DRbRunner.new(config_options(*args))
+  end
+
+  def config_options(*args)
+    RSpec::Core::ConfigurationOptions.new(args)
+  end
+
+  context "without server running" do
+    it "raises an error" do
+      expect { runner.run(err, out) }.to raise_error(DRb::DRbConnError)
+    end
+
+    after { DRb.stop_service }
+  end
+
+  describe "--drb-port" do
+    def with_RSPEC_DRB_set_to(val)
+      with_env_vars('RSPEC_DRB' => val) { yield }
+    end
+
+    context "without RSPEC_DRB environment variable set" do
+      it "defaults to 8989" do
+        with_RSPEC_DRB_set_to(nil) do
+          expect(runner.drb_port).to eq(8989)
+        end
+      end
+
+      it "sets the DRb port" do
+        with_RSPEC_DRB_set_to(nil) do
+          expect(runner("--drb-port", "1234").drb_port).to eq(1234)
+          expect(runner("--drb-port", "5678").drb_port).to eq(5678)
+        end
+      end
+    end
+
+    context "with RSPEC_DRB environment variable set" do
+      context "without config variable set" do
+        it "uses RSPEC_DRB value" do
+          with_RSPEC_DRB_set_to('9000') do
+            expect(runner.drb_port).to eq("9000")
+          end
+        end
+      end
+
+      context "and config variable set" do
+        it "uses configured value" do
+          with_RSPEC_DRB_set_to('9000') do
+            expect(runner(*%w[--drb-port 5678]).drb_port).to eq(5678)
+          end
+        end
+      end
+    end
+  end
+
+  context "with server running", :slow do
+    class SimpleDRbSpecServer
+      def self.run(argv, err, out)
+        options = RSpec::Core::ConfigurationOptions.new(argv)
+        config  = RSpec::Core::Configuration.new
+        RSpec.configuration = config
+        RSpec::Core::Runner.new(options, config).run(err, out)
+      end
+    end
+
+    before(:all) do
+      @drb_port = '8990'
+      @drb_example_file_counter = 0
+      DRb::start_service("druby://127.0.0.1:#{@drb_port}", SimpleDRbSpecServer)
+    end
+
+    after(:all) do
+      DRb::stop_service
+    end
+
+    it "returns 0 if spec passes" do
+      result = runner("--drb-port", @drb_port, passing_spec_filename).run(err, out)
+      expect(result).to be(0)
+    end
+
+    it "returns 1 if spec fails" do
+      result = runner("--drb-port", @drb_port, failing_spec_filename).run(err, out)
+      expect(result).to be(1)
+    end
+
+    it "outputs colorized text when running with --color option" do
+      failure_symbol = "\e[#{RSpec::Core::Formatters::ConsoleCodes.console_code_for(:red)}mF"
+      allow(out).to receive_messages(:tty? => true)
+      runner(failing_spec_filename, "--color", "--drb-port", @drb_port).run(err, out)
+      expect(out.string).to include(failure_symbol)
+    end
+  end
+end
+
+RSpec.describe RSpec::Core::DRbOptions, :isolated_directory => true, :isolated_home => true do
+  include ConfigOptionsHelper
+
+  describe "DRB args" do
+    def drb_argv_for(args)
+      options = config_options_object(*args)
+      RSpec::Core::DRbRunner.new(options, RSpec.configuration).drb_argv
+    end
+
+    def drb_filter_manager_for(args)
+      configuration = RSpec::Core::Configuration.new
+      RSpec::Core::DRbRunner.new(config_options_object(*args), configuration).drb_argv
+      configuration.filter_manager
+    end
+
+    it "preserves extra arguments" do
+      allow(File).to receive(:exist?) { false }
+      expect(drb_argv_for(%w[ a --drb b --color c ])).to match_array %w[ --color a b c ]
+    end
+
+    %w(--color --fail-fast --profile --backtrace --tty).each do |option|
+      it "includes #{option}" do
+        expect(drb_argv_for([option])).to include(option)
+      end
+    end
+
+    it "includes --failure-exit-code" do
+      expect(drb_argv_for(%w[--failure-exit-code 2])).to include("--failure-exit-code", "2")
+    end
+
+    it "includes --options" do
+      expect(drb_argv_for(%w[--options custom.opts])).to include("--options", "custom.opts")
+    end
+
+    it "includes --order" do
+      expect(drb_argv_for(%w[--order random])).to include('--order', 'random')
+    end
+
+    context "with --example" do
+      it "includes --example" do
+        expect(drb_argv_for(%w[--example foo])).to include("--example", "foo")
+      end
+
+      it "unescapes characters which were escaped upon storing --example originally" do
+        expect(drb_argv_for(["--example", "foo\\ bar"])).to include("--example", "foo bar")
+      end
+    end
+
+    context "with tags" do
+      it "includes the inclusion tags" do
+        expect(drb_argv_for ["--tag", "tag"]).to eq(["--tag", "tag"])
+      end
+
+      it "includes the inclusion tags with values" do
+        expect(drb_argv_for ["--tag", "tag:foo"]).to eq(["--tag", "tag:foo"])
+      end
+
+      it "leaves inclusion tags intact" do
+        rules = drb_filter_manager_for(%w[ --tag tag ]).inclusions.rules
+        expect(rules).to eq( {:tag=>true} )
+      end
+
+      it "leaves inclusion tags with values intact" do
+        rules = drb_filter_manager_for(%w[ --tag tag:foo ]).inclusions.rules
+        expect(rules).to eq( {:tag=>'foo'} )
+      end
+
+      it "includes the exclusion tags" do
+        expect(drb_argv_for ["--tag", "~tag"]).to eq(["--tag", "~tag"])
+      end
+
+      it "includes the exclusion tags with values" do
+        expect(drb_argv_for ["--tag", "~tag:foo"]).to eq(["--tag", "~tag:foo"])
+      end
+
+      it "leaves exclusion tags intact" do
+        rules = drb_filter_manager_for(%w[ --tag ~tag ]).exclusions.rules
+        expect(rules).to eq( {:tag => true} )
+      end
+
+      it "leaves exclusion tags with values intact" do
+        rules = drb_filter_manager_for(%w[ --tag ~tag:foo ]).exclusions.rules
+        expect(rules).to eq( {:tag => 'foo'} )
+      end
+    end
+
+    context "with formatters" do
+      it "includes the formatters" do
+        expect(drb_argv_for ["--format", "d"]).to eq(["--format", "d"])
+      end
+
+      it "leaves formatters intact" do
+        coo = config_options_object("--format", "d")
+        RSpec::Core::DRbRunner.new(coo, RSpec::Core::Configuration.new).drb_argv
+        expect(coo.options[:formatters]).to eq([["d"]])
+      end
+
+      it "leaves output intact" do
+        coo = config_options_object("--format", "p", "--out", "foo.txt", "--format", "d")
+        RSpec::Core::DRbRunner.new(coo, RSpec::Core::Configuration.new).drb_argv
+        expect(coo.options[:formatters]).to eq([["p","foo.txt"],["d"]])
+      end
+    end
+
+    context "with --out" do
+      it "combines with formatters" do
+        argv = drb_argv_for(%w[--format h --out report.html])
+        expect(argv).to  eq(%w[--format h --out report.html])
+      end
+    end
+
+    context "with -I libs" do
+      it "includes -I" do
+        expect(drb_argv_for(%w[-I a_dir])).to eq(%w[-I a_dir])
+      end
+
+      it "includes multiple paths" do
+        argv = drb_argv_for(%w[-I dir_1 -I dir_2 -I dir_3])
+        expect(argv).to  eq(%w[-I dir_1 -I dir_2 -I dir_3])
+      end
+    end
+
+    context "with --require" do
+      it "includes --require" do
+        expect(drb_argv_for(%w[--require a_path])).to eq(%w[--require a_path])
+      end
+
+      it "includes multiple paths" do
+        argv = drb_argv_for(%w[--require dir/ --require file.rb])
+        expect(argv).to  eq(%w[--require dir/ --require file.rb])
+      end
+    end
+
+    context "--drb specified in ARGV" do
+      it "renders all the original arguments except --drb" do
+        argv = drb_argv_for(%w[ --drb --color --format s --example pattern
+                                --profile --backtrace -I
+                                path/a -I path/b --require path/c --require
+                                path/d])
+        expect(argv).to eq(%w[ --color --profile --backtrace --example pattern --format s -I path/a -I path/b --require path/c --require path/d])
+      end
+    end
+
+    context "--drb specified in the options file" do
+      it "renders all the original arguments except --drb" do
+        File.open("./.rspec", "w") {|f| f << "--drb --color"}
+        drb_argv = drb_argv_for(%w[ --tty --format s --example pattern --profile --backtrace ])
+        expect(drb_argv).to eq(%w[ --color --profile --backtrace --tty --example pattern --format s])
+      end
+    end
+
+    context "--drb specified in ARGV and the options file" do
+      it "renders all the original arguments except --drb" do
+        File.open("./.rspec", "w") {|f| f << "--drb --color"}
+        argv = drb_argv_for(%w[ --drb --format s --example pattern --profile --backtrace])
+        expect(argv).to eq(%w[ --color --profile --backtrace --example pattern --format s])
+      end
+    end
+
+    context "--drb specified in ARGV and in as ARGV-specified --options file" do
+      it "renders all the original arguments except --drb and --options" do
+        File.open("./.rspec", "w") {|f| f << "--drb --color"}
+        argv = drb_argv_for(%w[ --drb --format s --example pattern --profile --backtrace])
+        expect(argv).to eq(%w[ --color --profile --backtrace --example pattern --format s ])
+      end
+    end
+
+    describe "--drb, -X" do
+      it "does not send --drb back to the parser after parsing options" do
+        expect(drb_argv_for(%w[--drb --color])).not_to include("--drb")
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/dsl_spec.rb b/rspec-core/spec/rspec/core/dsl_spec.rb
new file mode 100644
index 0000000..cb204f7
--- /dev/null
+++ b/rspec-core/spec/rspec/core/dsl_spec.rb
@@ -0,0 +1,105 @@
+require 'rspec/support/spec/in_sub_process'
+
+main = self
+
+RSpec.describe "The RSpec DSL" do
+  include RSpec::Support::InSubProcess
+
+  shared_examples_for "dsl methods" do |*method_names|
+    context "when expose_dsl_globally is enabled" do
+      def enable
+        in_sub_process do
+          changing_expose_dsl_globally do
+            RSpec.configuration.expose_dsl_globally = true
+            expect(RSpec.configuration.expose_dsl_globally?).to eq true
+          end
+
+          yield
+        end
+      end
+
+      it 'makes them only available off of `RSpec`, `main` and modules' do
+        enable do
+          expect(::RSpec).to respond_to(*method_names)
+          expect(main).to respond_to(*method_names)
+          expect(Module.new).to respond_to(*method_names)
+
+          expect(Object.new).not_to respond_to(*method_names)
+        end
+      end
+    end
+
+    context "when expose_dsl_globally is disabled" do
+      def disable
+        in_sub_process do
+          changing_expose_dsl_globally do
+            RSpec.configuration.expose_dsl_globally = false
+            expect(RSpec.configuration.expose_dsl_globally?).to eq false
+          end
+
+          yield
+        end
+      end
+
+      it 'makes them only available off of `RSpec`' do
+        disable do
+          expect(::RSpec).to respond_to(*method_names)
+
+          expect(main).not_to respond_to(*method_names)
+          expect(Module.new).not_to respond_to(*method_names)
+          expect(Object.new).not_to respond_to(*method_names)
+        end
+      end
+    end
+  end
+
+  describe "built in DSL methods" do
+    include_examples "dsl methods", :describe, :context, :shared_examples, :shared_examples_for, :shared_context do
+      def changing_expose_dsl_globally
+        yield
+      end
+    end
+  end
+
+  describe "custom example group aliases" do
+    context "when adding aliases before exposing the DSL globally" do
+      include_examples "dsl methods", :detail do
+        def changing_expose_dsl_globally
+          RSpec.configuration.alias_example_group_to(:detail)
+          yield
+        end
+      end
+    end
+
+    context "when adding aliases after exposing the DSL globally" do
+      include_examples "dsl methods", :detail do
+        def changing_expose_dsl_globally
+          yield
+          RSpec.configuration.alias_example_group_to(:detail)
+        end
+      end
+    end
+
+    context "when adding duplicate aliases" do
+      it "only a single alias is created" do
+        in_sub_process do
+          RSpec.configuration.alias_example_group_to(:detail)
+          RSpec.configuration.alias_example_group_to(:detail)
+          expect(RSpec::Core::DSL.example_group_aliases.count(:detail)).to eq(1)
+        end
+      end
+
+      it "does not undefine the alias multiple times", :issue => 1824 do
+        in_sub_process do
+          RSpec.configuration.expose_dsl_globally = true
+          RSpec.configuration.alias_example_group_to(:detail)
+          RSpec.configuration.alias_example_group_to(:detail)
+
+          expect {
+            RSpec.configuration.expose_dsl_globally = false
+          }.not_to raise_error
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/example_execution_result_spec.rb b/rspec-core/spec/rspec/core/example_execution_result_spec.rb
new file mode 100644
index 0000000..da60e62
--- /dev/null
+++ b/rspec-core/spec/rspec/core/example_execution_result_spec.rb
@@ -0,0 +1,140 @@
+module RSpec
+  module Core
+    class Example
+      RSpec.describe ExecutionResult do
+        it "supports ruby 2.1's `to_h` protocol" do
+          er = ExecutionResult.new
+          er.run_time = 17
+          er.pending_message = "just because"
+
+          expect(er.to_h).to include(
+            :run_time => 17,
+            :pending_message => "just because"
+          )
+        end
+
+        it 'includes all defined attributes in the `to_h` hash even if not set' do
+          expect(ExecutionResult.new.to_h).to include(
+            :status => nil,
+            :pending_message => nil
+          )
+        end
+
+        it 'provides a `pending_fixed?` predicate' do
+          er = ExecutionResult.new
+          expect { er.pending_fixed = true }.to change(er, :pending_fixed?).to(true)
+        end
+
+        describe "backwards compatibility" do
+          it 'supports indexed access like a hash' do
+            er = ExecutionResult.new
+            er.started_at = (started_at = ::Time.utc(2014, 3, 1, 12, 30))
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /execution_result/)
+            expect(er[:started_at]).to eq(started_at)
+          end
+
+          it 'supports indexed updates like a hash' do
+            er = ExecutionResult.new
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /execution_result/)
+            er[:started_at] = (started_at = ::Time.utc(2014, 3, 1, 12, 30))
+            expect(er.started_at).to eq(started_at)
+          end
+
+          it 'can get and set user defined attributes like with a hash' do
+            er = ExecutionResult.new
+            allow_deprecation
+            expect { er[:foo] = 3 }.to change { er[:foo] }.from(nil).to(3)
+            expect(er.to_h).to include(:foo => 3)
+          end
+
+          it 'supports `update` like a hash' do
+            er = ExecutionResult.new
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /execution_result/)
+            er.update(:pending_message => "some message", :exception => ArgumentError.new)
+            expect(er.pending_message).to eq("some message")
+            expect(er.exception).to be_a(ArgumentError)
+          end
+
+          it 'can set undefined attribute keys through any hash mutation method' do
+            allow_deprecation
+            er = ExecutionResult.new
+            er.update(:pending_message => "msg", :foo => 3)
+            expect(er.to_h).to include(:pending_message => "msg", :foo => 3)
+          end
+
+          it 'supports `merge` like a hash' do
+            er = ExecutionResult.new
+            er.exception = ArgumentError.new
+            er.pending_message = "just because"
+
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /execution_result/)
+            merged = er.merge(:exception => NotImplementedError.new, :foo => 3)
+
+            expect(merged).to include(
+              :exception => an_instance_of(NotImplementedError),
+              :pending_message => "just because",
+              :foo => 3
+            )
+
+            expect(er.exception).to be_an(ArgumentError)
+          end
+
+          it 'supports blocks for hash methods that support one' do
+            er = ExecutionResult.new
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /execution_result/)
+            expect(er.fetch(:foo) { 3 }).to eq(3)
+          end
+
+          # It's IndexError on 1.8.7, KeyError on 1.9+
+          fetch_not_found_error_class = defined?(::KeyError) ? ::KeyError : ::IndexError
+
+          specify '#fetch treats unset properties the same as a hash does' do
+            allow_deprecation
+            er = ExecutionResult.new
+            expect { er.fetch(:pending_message) }.to raise_error(fetch_not_found_error_class)
+            er.pending_message = "some msg"
+            expect(er.fetch(:pending_message)).to eq("some msg")
+          end
+
+          describe "status" do
+            it 'returns a string when accessed like a hash' do
+              er = ExecutionResult.new
+              expect(er[:status]).to eq(nil)
+              er.status = :failed
+              expect(er[:status]).to eq("failed")
+            end
+
+            it "sets the status to a symbol when assigned as a string via the hash interface" do
+              er = ExecutionResult.new
+              er[:status] = "failed"
+              expect(er.status).to eq(:failed)
+              er[:status] = nil
+              expect(er.status).to eq(nil)
+            end
+
+            it "is presented as a string when included in returned hashes" do
+              er = ExecutionResult.new
+              er.status = :failed
+              expect(er.merge(:foo => 3)).to include(:status => "failed", :foo => 3)
+
+              er.status = nil
+              expect(er.merge(:foo => 3)).to include(:status => nil, :foo => 3)
+            end
+
+            it "is updated to a symbol when updated as a string via `update`" do
+              er = ExecutionResult.new
+              er.update(:status => "passed")
+              expect(er.status).to eq(:passed)
+            end
+
+            it 'is presented as a symbol in `to_h`' do
+              er = ExecutionResult.new
+              er.status = :failed
+              expect(er.to_h).to include(:status => :failed)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/example_group_constants_spec.rb b/rspec-core/spec/rspec/core/example_group_constants_spec.rb
new file mode 100644
index 0000000..ebeefb7
--- /dev/null
+++ b/rspec-core/spec/rspec/core/example_group_constants_spec.rb
@@ -0,0 +1,15 @@
+# encoding: utf-8
+
+RSpec.describe "::RSpec::Core::ExampleGroup" do
+  context "does not cause problems when users reference a top level constant of the same name" do
+    file_in_outer_group = File
+    example { expect(File).to eq ::File }
+    example { expect(file_in_outer_group).to be(::File) }
+
+    describe "File" do
+      file_in_inner_group = File
+      example { expect(File).to eq ::File }
+      example { expect(file_in_inner_group).to be(::File) }
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/example_group_spec.rb b/rspec-core/spec/rspec/core/example_group_spec.rb
new file mode 100644
index 0000000..f191757
--- /dev/null
+++ b/rspec-core/spec/rspec/core/example_group_spec.rb
@@ -0,0 +1,1787 @@
+# encoding: utf-8
+
+module RSpec::Core
+  RSpec.describe ExampleGroup do
+    it_behaves_like "metadata hash builder" do
+      def metadata_hash(*args)
+        group = RSpec.describe('example description', *args)
+        group.metadata
+      end
+    end
+
+    %w[ expect double spy ].each do |method|
+      context "when calling `#{method}`, an example API, on an example group" do
+        it "tells the user they are in the wrong scope for that API" do
+          expect {
+            RSpec.describe { __send__(method, "foo") }
+          }.to raise_error(ExampleGroup::WrongScopeError)
+        end
+      end
+    end
+
+    %w[ describe context let before it it_behaves_like ].each do |method|
+      context "when calling `#{method}`, an example group API, from within an example" do
+        it "tells the user they are in the wrong scope for that API" do
+          ex = nil
+
+          RSpec.describe do
+            ex = example { __send__(method, "foo") }
+          end.run
+
+          expect(ex).to fail_with(ExampleGroup::WrongScopeError)
+        end
+      end
+    end
+
+    it "surfaces NameError from an example group for other missing APIs, like normal" do
+      expect {
+        RSpec.describe { foobar }
+      }.to raise_error(NameError, /foobar/)
+    end
+
+    it "surfaces NameError from an example for other missing APIs, like normal" do
+      ex = nil
+
+      RSpec.describe do
+        ex = example { foobar }
+      end.run
+
+      expect(ex).to fail_with(NameError)
+    end
+
+    context "when RSpec.configuration.format_docstrings is set to a block" do
+      it "formats the description with that block" do
+        RSpec.configuration.format_docstrings { |s| s.upcase }
+        group = RSpec.describe(' an example ')
+        expect(group.description).to eq(' AN EXAMPLE ')
+      end
+    end
+
+    it 'does not treat the first argument as a metadata key even if it is a symbol' do
+      group = RSpec.describe(:symbol)
+      expect(group.metadata).not_to include(:symbol)
+    end
+
+    it 'treats the first argument as part of the description when it is a symbol' do
+      group = RSpec.describe(:symbol)
+      expect(group.description).to eq("symbol")
+    end
+
+    describe "constant naming" do
+      around do |ex|
+        before_constants = RSpec::ExampleGroups.constants
+        ex.run
+        after_constants = RSpec::ExampleGroups.constants
+
+        (after_constants - before_constants).each do |name|
+          RSpec::ExampleGroups.send(:remove_const, name)
+        end
+      end
+
+      if RUBY_VERSION == "1.9.2"
+        RSpec::Matchers.define :have_class_const do |class_name|
+          match do |group|
+            class_name.gsub!('::','_::')
+            class_name << '_'
+            group.name == "RSpec::ExampleGroups::#{class_name}" &&
+            group == class_name.split('::').inject(RSpec::ExampleGroups) do |mod, name|
+              mod.const_get(name)
+            end
+          end
+        end
+      else
+        RSpec::Matchers.define :have_class_const do |class_name, _|
+          match do |group|
+            group.name == "RSpec::ExampleGroups::#{class_name}" &&
+            group == class_name.split('::').inject(RSpec::ExampleGroups) do |mod, name|
+              mod.const_get(name)
+            end
+          end
+        end
+      end
+
+      it 'gives groups friendly human readable class names' do
+        stub_const("MyGem::Klass", Class.new)
+        parent = RSpec.describe(MyGem::Klass)
+        expect(parent).to have_class_const("MyGemKlass")
+      end
+
+      it 'nests constants to match the group nesting' do
+        grandparent = RSpec.describe("The grandparent")
+        parent      = grandparent.describe("the parent")
+        child       = parent.describe("the child")
+
+        expect(parent).to have_class_const("TheGrandparent::TheParent")
+        expect(child).to have_class_const("TheGrandparent::TheParent::TheChild")
+      end
+
+      it 'removes non-ascii characters from the const name since some rubies barf on that' do
+        group = RSpec.describe("A chinese character: 们")
+        expect(group).to have_class_const("AChineseCharacter")
+      end
+
+      it 'prefixes the const name with "Nested" if needed to make a valid const' do
+        expect {
+          ExampleGroup.const_set("1B", Object.new)
+        }.to raise_error(NameError)
+
+        group = RSpec.describe("1B")
+        expect(group).to have_class_const("Nested1B")
+      end
+
+      it 'does not warn when defining a Config example group (since RbConfig triggers warnings when Config is referenced)' do
+        expect { RSpec.describe("Config") }.not_to output.to_stderr
+      end
+
+      it 'ignores top level constants that have the same name' do
+        parent = RSpec.describe("Some Parent Group")
+        child  = parent.describe("Hash")
+        # This would be `SomeParentGroup::Hash_2` if we didn't ignore the top level `Hash`
+        expect(child).to have_class_const("SomeParentGroup::Hash")
+      end
+
+      it 'disambiguates name collisions by appending a number', :unless => RUBY_VERSION == '1.9.2' do
+        groups = 10.times.map { RSpec.describe("Collision") }
+        expect(groups[0]).to have_class_const("Collision")
+        expect(groups[1]).to have_class_const("Collision_2")
+        expect(groups[8]).to have_class_const("Collision_9")
+
+        if RUBY_VERSION.to_f > 1.8 && !(defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx')
+          # on 1.8.7, rbx "Collision_9".next => "Collisioo_0"
+          expect(groups[9]).to have_class_const("Collision_10")
+        end
+      end
+
+      it 'identifies unnamed groups as "Anonymous"' do
+        # Wrap the anonymous group is a uniquely named one,
+        # so the presence of another anonymous group in our
+        # test suite doesn't cause an unexpected number
+        # to be appended.
+        group    = RSpec.describe("name of unnamed group")
+        subgroup = group.describe
+        expect(subgroup).to have_class_const("NameOfUnnamedGroup::Anonymous")
+      end
+
+      it 'assigns the const before evaling the group so error messages include the name' do
+        expect {
+          RSpec.describe("Calling an undefined method") { foo }
+        }.to raise_error(/ExampleGroups::CallingAnUndefinedMethod/)
+      end
+
+      it 'does not have problems with example groups named "Core"', :unless => RUBY_VERSION == '1.9.2' do
+        RSpec.describe("Core")
+        expect(defined?(::RSpec::ExampleGroups::Core)).to be_truthy
+
+        # The original bug was triggered when a group was defined AFTER one named `Core`,
+        # due to it not using the fully qualified `::RSpec::Core::ExampleGroup` constant.
+        group = RSpec.describe("Another group")
+        expect(group).to have_class_const("AnotherGroup")
+      end
+
+      it 'does not have problems with example groups named "RSpec"', :unless => RUBY_VERSION == '1.9.2' do
+        RSpec.describe("RSpec")
+        expect(defined?(::RSpec::ExampleGroups::RSpec)).to be_truthy
+
+        # The original bug was triggered when a group was defined AFTER one named `RSpec`,
+        # due to it not using the fully qualified `::RSpec::Core::ExampleGroup` constant.
+        group = RSpec.describe("Yet Another group")
+        expect(group).to have_class_const("YetAnotherGroup")
+      end
+    end
+
+    describe "ordering" do
+      context "when tagged with `:order => :defined`" do
+        it 'orders the subgroups and examples in defined order regardless of global order' do
+          RSpec.configuration.order = :random
+
+          run_order = []
+          group = RSpec.describe "outer", :order => :defined do
+            context "subgroup 1" do
+              example { run_order << :g1_e1 }
+              example { run_order << :g1_e2 }
+            end
+
+            context "subgroup 2" do
+              example { run_order << :g2_e1 }
+              example { run_order << :g2_e2 }
+            end
+          end
+
+          group.run
+          expect(run_order).to eq([:g1_e1, :g1_e2, :g2_e1, :g2_e2])
+        end
+      end
+
+      context "when tagged with an unrecognized ordering" do
+        let(:run_order) { [] }
+        let(:definition_line) { __LINE__ + 4 }
+        let(:group) do
+          order = self.run_order
+
+          RSpec.describe "group", :order => :unrecognized do
+            example { order << :ex_1 }
+            example { order << :ex_2 }
+          end
+        end
+
+        before do
+          RSpec.configuration.register_ordering(:global, &:reverse)
+          allow(self.group).to receive(:warn)
+        end
+
+        it 'falls back to the global ordering' do
+          self.group.run
+          expect(self.run_order).to eq([:ex_2, :ex_1])
+        end
+
+        it 'prints a warning so users are notified of their mistake' do
+          warning = nil
+          allow(self.group).to receive(:warn) { |msg| warning = msg }
+
+          self.group.run
+
+          expect(warning).to match(/unrecognized/)
+          expect(warning).to match(/#{File.basename __FILE__}:#{definition_line}/)
+        end
+      end
+
+      context "when tagged with a custom ordering" do
+        def ascending_numbers
+          lambda { |g| Integer(g.description[/\d+/]) }
+        end
+
+        it 'uses the custom orderings' do
+          RSpec.configure do |c|
+            c.register_ordering :custom do |items|
+              items.sort_by(&ascending_numbers)
+            end
+          end
+
+          run_order = []
+          group = RSpec.describe "outer", :order => :custom do
+            example("e2") { run_order << :e2 }
+            example("e1") { run_order << :e1 }
+
+            context "subgroup 2" do
+              example("ex 3") { run_order << :g2_e3 }
+              example("ex 1") { run_order << :g2_e1 }
+              example("ex 2") { run_order << :g2_e2 }
+            end
+
+            context "subgroup 1" do
+              example("ex 2") { run_order << :g1_e2 }
+              example("ex 1") { run_order << :g1_e1 }
+              example("ex 3") { run_order << :g1_e3 }
+            end
+
+            context "subgroup 3" do
+              example("ex 2") { run_order << :g3_e2 }
+              example("ex 3") { run_order << :g3_e3 }
+              example("ex 1") { run_order << :g3_e1 }
+            end
+          end
+
+          group.run
+
+          expect(run_order).to eq([
+            :e1,    :e2,
+            :g1_e1, :g1_e2, :g1_e3,
+            :g2_e1, :g2_e2, :g2_e3,
+            :g3_e1, :g3_e2, :g3_e3
+          ])
+        end
+      end
+    end
+
+    describe "top level group" do
+      it "runs its children" do
+        examples_run = []
+        group = RSpec.describe("parent") do
+          describe("child") do
+            it "does something" do |ex|
+              examples_run << ex
+            end
+          end
+        end
+
+        group.run
+        expect(examples_run.count).to eq(1)
+      end
+
+      context "with a failure in the top level group" do
+        it "runs its children " do
+          examples_run = []
+          group = RSpec.describe("parent") do
+            it "fails" do |ex|
+              examples_run << ex
+              raise "fail"
+            end
+            describe("child") do
+              it "does something" do |ex|
+                examples_run << ex
+              end
+            end
+          end
+
+          group.run
+          expect(examples_run.count).to eq(2)
+        end
+      end
+
+      describe "descendants" do
+        it "returns self + all descendants" do
+          group = RSpec.describe("parent") do
+            describe("child") do
+              describe("grandchild 1") {}
+              describe("grandchild 2") {}
+            end
+          end
+          expect(group.descendants.size).to eq(4)
+        end
+      end
+    end
+
+    describe "child" do
+      it "is known by parent" do
+        parent = RSpec.describe
+        child = parent.describe
+        expect(parent.children).to eq([child])
+      end
+
+      it "is not registered in world" do
+        world = RSpec::Core::World.new
+        parent = RSpec.describe
+        world.register(parent)
+        parent.describe
+        expect(world.example_groups).to eq([parent])
+      end
+    end
+
+    describe "filtering" do
+      let(:world) { World.new }
+      before { allow(RSpec).to receive_messages(:world => self.world) }
+
+      shared_examples "matching filters" do
+        context "inclusion" do
+          before do
+            filter_manager = FilterManager.new
+            filter_manager.include filter_metadata
+            allow(self.world).to receive_messages(:filter_manager => filter_manager)
+          end
+
+          it "includes examples in groups matching filter" do
+            group = RSpec.describe("does something", spec_metadata)
+            all_examples = [ group.example("first"), group.example("second") ]
+
+            expect(group.filtered_examples).to eq(all_examples)
+          end
+
+          it "includes examples directly matching filter" do
+            group = RSpec.describe("does something")
+            filtered_examples = [
+              group.example("first", spec_metadata),
+              group.example("second", spec_metadata)
+            ]
+            group.example("third (not-filtered)")
+
+            expect(group.filtered_examples).to eq(filtered_examples)
+          end
+        end
+
+        context "exclusion" do
+          before do
+            filter_manager = FilterManager.new
+            filter_manager.exclude filter_metadata
+            allow(self.world).to receive_messages(:filter_manager => filter_manager)
+          end
+
+          it "excludes examples in groups matching filter" do
+            group = RSpec.describe("does something", spec_metadata)
+            [ group.example("first"), group.example("second") ]
+
+            expect(group.filtered_examples).to be_empty
+          end
+
+          it "excludes examples directly matching filter" do
+            group = RSpec.describe("does something")
+            [
+              group.example("first", spec_metadata),
+              group.example("second", spec_metadata)
+            ]
+            unfiltered_example = group.example("third (not-filtered)")
+
+            expect(group.filtered_examples).to eq([unfiltered_example])
+          end
+        end
+      end
+
+      context "matching false" do
+        let(:spec_metadata)    { { :awesome => false }}
+
+        context "against false" do
+          let(:filter_metadata)  { { :awesome => false }}
+          include_examples "matching filters"
+        end
+
+        context "against 'false'" do
+          let(:filter_metadata)  { { :awesome => 'false' }}
+          include_examples "matching filters"
+        end
+
+        context "against :false" do
+          let(:filter_metadata)  { { :awesome => :false }}
+          include_examples "matching filters"
+        end
+      end
+
+      context "matching true" do
+        let(:spec_metadata)    { { :awesome => true }}
+
+        context "against true" do
+          let(:filter_metadata)  { { :awesome => true }}
+          include_examples "matching filters"
+        end
+
+        context "against 'true'" do
+          let(:filter_metadata)  { { :awesome => 'true' }}
+          include_examples "matching filters"
+        end
+
+        context "against :true" do
+          let(:filter_metadata)  { { :awesome => :true }}
+          include_examples "matching filters"
+        end
+      end
+
+      context "matching a string" do
+        let(:spec_metadata)    { { :type => 'special' }}
+
+        context "against a string" do
+          let(:filter_metadata)  { { :type => 'special' }}
+          include_examples "matching filters"
+        end
+
+        context "against a symbol" do
+          let(:filter_metadata)  { { :type => :special }}
+          include_examples "matching filters"
+        end
+      end
+
+      context "matching a symbol" do
+        let(:spec_metadata)    { { :type => :special }}
+
+        context "against a string" do
+          let(:filter_metadata)  { { :type => 'special' }}
+          include_examples "matching filters"
+        end
+
+        context "against a symbol" do
+          let(:filter_metadata)  { { :type => :special }}
+          include_examples "matching filters"
+        end
+      end
+
+      context "with no filters" do
+        it "returns all" do
+          group = RSpec.describe
+          allow(group).to receive(:world) { self.world }
+          example = group.example("does something")
+          expect(group.filtered_examples).to eq([example])
+        end
+      end
+
+      context "with no examples or groups that match filters" do
+        it "returns none" do
+          filter_manager = FilterManager.new
+          filter_manager.include :awesome => false
+          allow(self.world).to receive_messages(:filter_manager => filter_manager)
+          group = RSpec.describe
+          allow(group).to receive(:world) { self.world }
+          group.example("does something")
+          expect(group.filtered_examples).to eq([])
+        end
+      end
+    end
+
+    describe '#described_class' do
+
+      context "with a constant as the first parameter" do
+        it "is that constant" do
+          expect(RSpec.describe(Object) { }.described_class).to eq(Object)
+        end
+      end
+
+      context "with a string as the first parameter" do
+        it "is nil" do
+          expect(RSpec.describe("i'm a computer") { }.described_class).to be_nil
+        end
+      end
+
+      context "with a constant in an outer group" do
+        context "and a string in an inner group" do
+          it "is the top level constant" do
+            group = RSpec.describe(String) do
+              describe "inner" do
+                example "described_class is String" do
+                  expect(described_class).to eq(String)
+                end
+              end
+            end
+
+            expect(group.run).to be_truthy
+          end
+        end
+
+        context "and metadata redefinition after `described_class` call" do
+          it "is the redefined level constant" do
+            group = RSpec.describe(String) do
+              described_class
+              metadata[:described_class] = Object
+              describe "inner" do
+                example "described_class is Object" do
+                  expect(described_class).to eq(Object)
+                end
+              end
+            end
+
+            expect(group.run).to be_truthy
+          end
+        end
+      end
+
+      context "in a nested group" do
+        it "inherits the described class/module from the outer group" do
+          group = RSpec.describe(String) do
+            describe "nested" do
+              example "describes is String" do
+                expect(described_class).to eq(String)
+              end
+            end
+          end
+
+          expect(group.run).to be_truthy, "expected examples in group to pass"
+        end
+
+        context "when a class is passed" do
+          def described_class_value
+            value = nil
+
+            RSpec.describe(String) do
+              yield if block_given?
+              describe Array do
+                example { value = described_class }
+              end
+            end.run
+
+            value
+          end
+
+          it "overrides the described class" do
+            expect(described_class_value).to eq(Array)
+          end
+
+          it "overrides the described class even when described_class is referenced in the outer group" do
+            expect(described_class_value { described_class }).to eq(Array)
+          end
+        end
+      end
+
+      context "for `describe(SomeClass)` within a `describe 'some string' group" do
+        def define_and_run_group(define_outer_example = false)
+          outer_described_class = inner_described_class = nil
+
+          RSpec.describe("some string") do
+            example { outer_described_class = described_class } if define_outer_example
+
+            describe Array do
+              example { inner_described_class = described_class }
+            end
+          end.run
+
+          return outer_described_class, inner_described_class
+        end
+
+        it "has a `nil` described_class in the outer group" do
+          outer_described_class, _ = define_and_run_group(:define_outer_example)
+          expect(outer_described_class).to be(nil)
+        end
+
+        it "has the inner described class as the described_class of the inner group" do
+          _, inner_described_class = define_and_run_group
+          expect(inner_described_class).to be(Array)
+
+          # This is weird, but in RSpec 2.12 (and before, presumably),
+          # the `described_class` value would be incorrect if there was an
+          # example in the outer group, and correct if there was not one.
+          _, inner_described_class = define_and_run_group(:define_outer_example)
+          expect(inner_described_class).to be(Array)
+        end
+      end
+    end
+
+    describe '#described_class' do
+      it "is the same as described_class" do
+        expect(self.class.described_class).to eq(self.class.described_class)
+      end
+    end
+
+    describe '#description' do
+      it "grabs the description from the metadata" do
+        group = RSpec.describe(Object, "my desc") { }
+        expect(group.description).to eq(group.metadata[:description])
+      end
+    end
+
+    describe '#metadata' do
+      it "adds the third parameter to the metadata" do
+        expect(RSpec.describe(Object, nil, 'foo' => 'bar') { }.metadata).to include({ "foo" => 'bar' })
+      end
+
+      it "adds the the file_path to metadata" do
+        expect(RSpec.describe(Object) { }.metadata[:file_path]).to eq(relative_path(__FILE__))
+      end
+
+      it "has a reader for file_path" do
+        expect(RSpec.describe(Object) { }.file_path).to eq(relative_path(__FILE__))
+      end
+
+      it "adds the line_number to metadata" do
+        expect(RSpec.describe(Object) { }.metadata[:line_number]).to eq(__LINE__)
+      end
+    end
+
+    [:focus, :fexample, :fit, :fspecify].each do |example_alias|
+      describe ".#{example_alias}" do
+        let(:focused_example) { RSpec.describe.send example_alias, "a focused example" }
+
+        it 'defines an example that can be filtered with :focus => true' do
+          expect(focused_example.metadata[:focus]).to be_truthy
+        end
+      end
+    end
+
+    describe "#before, after, and around hooks" do
+      describe "scope aliasing" do
+        it "aliases the `:context` hook scope to `:all` for before-hooks" do
+          group = RSpec.describe
+          order = []
+          group.before(:context) { order << :before_context }
+          group.example("example") { order << :example }
+          group.example("example") { order << :example }
+
+          group.run
+          expect(order).to eq([:before_context, :example, :example])
+        end
+
+        it "aliases the `:example` hook scope to `:each` for before-hooks" do
+          group = RSpec.describe
+          order = []
+          group.before(:example) { order << :before_example }
+          group.example("example") { order << :example }
+          group.example("example") { order << :example }
+
+          group.run
+          expect(order).to eq([:before_example, :example, :before_example, :example])
+        end
+
+        it "aliases the `:context` hook scope to `:all` for after-hooks" do
+          group = RSpec.describe
+          order = []
+          group.example("example") { order << :example }
+          group.example("example") { order << :example }
+          group.after(:context) { order << :after_context }
+
+          group.run
+          expect(order).to eq([:example, :example, :after_context])
+        end
+
+        it "aliases the `:example` hook scope to `:each` for after-hooks" do
+          group = RSpec.describe
+          order = []
+          group.example("example") { order << :example }
+          group.example("example") { order << :example }
+          group.after(:example) { order << :after_example }
+
+          group.run
+          expect(order).to eq([:example, :after_example, :example, :after_example])
+        end
+      end
+
+      it "runs the before alls in order" do
+        group = RSpec.describe
+        order = []
+        group.before(:all) { order << 1 }
+        group.before(:all) { order << 2 }
+        group.before(:all) { order << 3 }
+        group.example("example") {}
+
+        group.run
+
+        expect(order).to eq([1,2,3])
+      end
+
+      it "does not set RSpec.world.wants_to_quit in case of an error in before all (without fail_fast?)" do
+        group = RSpec.describe
+        group.before(:all) { raise "error in before all" }
+        group.example("example") {}
+
+        group.run
+        expect(RSpec.world.wants_to_quit).to be_falsey
+      end
+
+      it "runs the before eachs in order" do
+        group = RSpec.describe
+        order = []
+        group.before(:each) { order << 1 }
+        group.before(:each) { order << 2 }
+        group.before(:each) { order << 3 }
+        group.example("example") {}
+
+        group.run
+
+        expect(order).to eq([1,2,3])
+      end
+
+      it "runs the after eachs in reverse order" do
+        group = RSpec.describe
+        order = []
+        group.after(:each) { order << 1 }
+        group.after(:each) { order << 2 }
+        group.after(:each) { order << 3 }
+        group.example("example") {}
+
+        group.run
+
+        expect(order).to eq([3,2,1])
+      end
+
+      it "runs the after alls in reverse order" do
+        group = RSpec.describe
+        order = []
+        group.after(:all) { order << 1 }
+        group.after(:all) { order << 2 }
+        group.after(:all) { order << 3 }
+        group.example("example") {}
+
+        group.run
+
+        expect(order).to eq([3,2,1])
+      end
+
+      it "only runs before/after(:all) hooks from example groups that have specs that run" do
+        hooks_run = []
+
+        RSpec.configure do |c|
+          c.filter_run :focus => true
+        end
+
+        unfiltered_group = RSpec.describe "unfiltered" do
+          before(:all) { hooks_run << :unfiltered_before_all }
+          after(:all)  { hooks_run << :unfiltered_after_all  }
+
+          context "a subcontext" do
+            it("has an example") { }
+          end
+        end
+
+        filtered_group = RSpec.describe "filtered", :focus => true do
+          before(:all) { hooks_run << :filtered_before_all }
+          after(:all)  { hooks_run << :filtered_after_all  }
+
+          context "a subcontext" do
+            it("has an example") { }
+          end
+        end
+
+        unfiltered_group.run
+        filtered_group.run
+
+        expect(hooks_run).to eq([:filtered_before_all, :filtered_after_all])
+      end
+
+      it "runs before_all_defined_in_config, before all, before each, example, after each, after all, after_all_defined_in_config in that order" do
+        order = []
+
+        RSpec.configure do |c|
+          c.before(:all) { order << :before_all_defined_in_config }
+          c.after(:all) { order << :after_all_defined_in_config }
+        end
+
+        group = RSpec.describe
+        group.before(:all)  { order << :top_level_before_all  }
+        group.before(:each) { order << :before_each }
+        group.after(:each)  { order << :after_each  }
+        group.after(:all)   { order << :top_level_after_all   }
+        group.example("top level example") { order << :top_level_example }
+
+        context1 = group.describe("context 1")
+        context1.before(:all) { order << :nested_before_all }
+        context1.example("nested example 1") { order << :nested_example_1 }
+
+        context2 = group.describe("context 2")
+        context2.after(:all) { order << :nested_after_all }
+        context2.example("nested example 2") { order << :nested_example_2 }
+
+        group.run
+
+        expect(order).to eq([
+          :before_all_defined_in_config,
+          :top_level_before_all,
+          :before_each,
+          :top_level_example,
+          :after_each,
+          :nested_before_all,
+          :before_each,
+          :nested_example_1,
+          :after_each,
+          :before_each,
+          :nested_example_2,
+          :after_each,
+          :nested_after_all,
+          :top_level_after_all,
+          :after_all_defined_in_config
+        ])
+      end
+
+      context "after(:all)" do
+        let(:outer) { RSpec.describe }
+        let(:inner) { outer.describe }
+
+        it "has access to state defined before(:all)" do
+          outer.before(:all) { @outer = "outer" }
+          inner.before(:all) { @inner = "inner" }
+
+          outer.after(:all) do
+            expect(@outer).to eq("outer")
+            expect(@inner).to eq("inner")
+          end
+          inner.after(:all) do
+            expect(@inner).to eq("inner")
+            expect(@outer).to eq("outer")
+          end
+
+          outer.run
+        end
+
+        it "cleans up ivars in after(:all)" do
+          outer.before(:all) { @outer = "outer" }
+          inner.before(:all) { @inner = "inner" }
+
+          outer.run
+
+          expect(inner.before_context_ivars[:@inner]).to be_nil
+          expect(inner.before_context_ivars[:@outer]).to be_nil
+          expect(outer.before_context_ivars[:@inner]).to be_nil
+          expect(outer.before_context_ivars[:@outer]).to be_nil
+        end
+      end
+
+      it "treats an error in before(:each) as a failure" do
+        group = RSpec.describe
+        group.before(:each) { raise "error in before each" }
+        example = group.example("equality") { expect(1).to eq(2) }
+        expect(group.run).to be(false)
+
+        expect(example.execution_result.exception.message).to eq("error in before each")
+      end
+
+      it "treats an error in before(:all) as a failure" do
+        group = RSpec.describe
+        group.before(:all) { raise "error in before all" }
+        example = group.example("equality") { expect(1).to eq(2) }
+        expect(group.run).to be_falsey
+
+        expect(example.metadata).not_to be_nil
+        expect(example.execution_result.exception).not_to be_nil
+        expect(example.execution_result.exception.message).to eq("error in before all")
+      end
+
+      it "exposes instance variables set in before(:all) from after(:all) even if a before(:all) error occurs" do
+        ivar_value_in_after_hook = nil
+
+        group = RSpec.describe do
+          before(:all) do
+            @an_ivar = :set_in_before_all
+            raise "fail"
+          end
+
+          after(:all) { ivar_value_in_after_hook = @an_ivar }
+
+          it("has a spec") { }
+        end
+
+        group.run
+        expect(ivar_value_in_after_hook).to eq(:set_in_before_all)
+      end
+
+      it "treats an error in before(:all) as a failure for a spec in a nested group" do
+        example = nil
+        group = RSpec.describe do
+          before(:all) { raise "error in before all" }
+
+          describe "nested" do
+            example = it("equality") { expect(1).to eq(2) }
+          end
+        end
+        group.run
+
+        expect(example.metadata).not_to be_nil
+        expect(example.execution_result.exception).not_to be_nil
+        expect(example.execution_result.exception.message).to eq("error in before all")
+      end
+
+      context "when an error occurs in an after(:all) hook" do
+        hooks_run = []
+
+        before(:each) do
+          hooks_run = []
+          allow(RSpec.configuration.reporter).to receive(:message)
+        end
+
+        let(:group) do
+          RSpec.describe do
+            after(:all) { hooks_run << :one; raise "An error in an after(:all) hook" }
+            after(:all) { hooks_run << :two; raise "A different hook raising an error" }
+            it("equality") { expect(1).to eq(1) }
+          end
+        end
+
+        it "allows the example to pass" do
+          self.group.run
+          example = self.group.examples.first
+          expect(example.execution_result.status).to eq(:passed)
+        end
+
+        it "rescues any error(s) and prints them out" do
+          expect(RSpec.configuration.reporter).to receive(:message).with(/An error in an after\(:all\) hook/)
+          expect(RSpec.configuration.reporter).to receive(:message).with(/A different hook raising an error/)
+          self.group.run
+        end
+
+        it "still runs both after blocks" do
+          self.group.run
+          expect(hooks_run).to eq [:two,:one]
+        end
+      end
+    end
+
+    describe ".pending" do
+      let(:group) { RSpec.describe { pending { fail } } }
+
+      it "generates a pending example" do
+        self.group.run
+        expect(self.group.examples.first).to be_pending
+      end
+
+      it "sets the pending message" do
+        self.group.run
+        expect(self.group.examples.first.execution_result.pending_message).to eq(RSpec::Core::Pending::NO_REASON_GIVEN)
+      end
+
+      it 'sets the backtrace to the example definition so it can be located by the user' do
+        file = RSpec::Core::Metadata.relative_path(__FILE__)
+        expected = [file, __LINE__ + 2].map(&:to_s)
+        group = RSpec.describe do
+          pending { }
+        end
+        group.run
+
+        actual = group.examples.first.exception.backtrace.first.split(':')[0..1]
+        expect(actual).to eq(expected)
+      end
+
+      it 'generates a pending example when no block is provided' do
+        group = RSpec.describe "group"
+        example = group.pending "just because"
+        group.run
+        expect(example).to be_pending
+      end
+    end
+
+    describe "pending with metadata" do
+      let(:group) { RSpec.describe {
+        example("unimplemented", :pending => true) { fail }
+      } }
+
+      it "generates a pending example" do
+        self.group.run
+        expect(self.group.examples.first).to be_pending
+      end
+
+      it "sets the pending message" do
+        self.group.run
+        expect(self.group.examples.first.execution_result.pending_message).to eq(RSpec::Core::Pending::NO_REASON_GIVEN)
+      end
+    end
+
+    describe "pending with message in metadata" do
+      let(:group) { RSpec.describe {
+        example("unimplemented", :pending => 'not done') { fail }
+      } }
+
+      it "generates a pending example" do
+        self.group.run
+        expect(self.group.examples.first).to be_pending
+      end
+
+      it "sets the pending message" do
+        self.group.run
+        expect(self.group.examples.first.execution_result.pending_message).to eq("not done")
+      end
+    end
+
+    describe ".skip" do
+      let(:group) { RSpec.describe { skip("skip this") { } } }
+
+      it "generates a skipped example" do
+        self.group.run
+        expect(self.group.examples.first).to be_skipped
+      end
+
+      it "sets the pending message" do
+        self.group.run
+        expect(self.group.examples.first.execution_result.pending_message).to eq(RSpec::Core::Pending::NO_REASON_GIVEN)
+      end
+    end
+
+    describe "skip with metadata" do
+      let(:group) { RSpec.describe {
+        example("skip this", :skip => true) { }
+      } }
+
+      it "generates a skipped example" do
+        self.group.run
+        expect(self.group.examples.first).to be_skipped
+      end
+
+      it "sets the pending message" do
+        self.group.run
+        expect(self.group.examples.first.execution_result.pending_message).to eq(RSpec::Core::Pending::NO_REASON_GIVEN)
+      end
+    end
+
+    describe "skip with message in metadata" do
+      let(:group) { RSpec.describe {
+        example("skip this", :skip => 'not done') { }
+      } }
+
+      it "generates a skipped example" do
+        self.group.run
+        expect(self.group.examples.first).to be_skipped
+      end
+
+      it "sets the pending message" do
+        self.group.run
+        expect(self.group.examples.first.execution_result.pending_message).to eq('not done')
+      end
+    end
+
+    %w[xit xspecify xexample].each do |method_name|
+      describe ".#{method_name}" do
+        let(:group) { RSpec.describe.tap {|x|
+          x.send(method_name, "is pending") { }
+        }}
+
+        it "generates a skipped example" do
+          self.group.run
+          expect(self.group.examples.first).to be_skipped
+        end
+
+        it "sets the pending message" do
+          self.group.run
+          expect(self.group.examples.first.execution_result.pending_message).to eq("Temporarily skipped with #{method_name}")
+        end
+      end
+    end
+
+    %w[ xdescribe xcontext ].each do |method_name|
+      describe ".#{method_name}" do
+        def extract_execution_results(group)
+          group.examples.map do |ex|
+            ex.metadata.fetch(:execution_result)
+          end
+        end
+
+        it 'generates a pending example group' do
+          group = ExampleGroup.send(method_name, "group") do
+            it("passes") { }
+            it("fails")  { expect(2).to eq(3) }
+          end
+          group.run
+
+          expect(extract_execution_results(group).map(&:to_h)).to match([
+            a_hash_including(
+              :status => :pending,
+              :pending_message => "Temporarily skipped with #{method_name}"
+            )
+          ] * 2)
+        end
+      end
+    end
+
+    %w[ fdescribe fcontext ].each do |method_name|
+      describe ".#{method_name}" do
+        def executed_examples_of(group)
+          examples = group.examples.select { |ex| ex.execution_result.started_at }
+          group.children.inject(examples) { |exs, child| exs + executed_examples_of(child) }
+        end
+
+        it "generates an example group that can be filtered with :focus" do
+          RSpec.configuration.filter_run :focus
+
+          parent_group = RSpec.describe do
+            describe "not focused" do
+              example("not focused example") { }
+            end
+
+            send(method_name, "focused") do
+              example("focused example") { }
+            end
+          end
+
+          parent_group.run
+
+          executed_descriptions = executed_examples_of(parent_group).map(&:description)
+          expect(executed_descriptions).to eq(["focused example"])
+        end
+      end
+    end
+
+    describe "setting pending metadata in parent" do
+      def extract_execution_results(group)
+        group.examples.map do |ex|
+          ex.metadata.fetch(:execution_result)
+        end
+      end
+
+      it 'marks every example as pending' do
+        group = RSpec.describe("group", :pending => true) do
+          it("passes") { }
+          it("fails", :pending => 'unimplemented')  { fail }
+        end
+        group.run
+
+        expect(extract_execution_results(group).map(&:to_h)).to match([
+          a_hash_including(
+            :status => :failed,
+            :pending_message => "No reason given"
+          ),
+          a_hash_including(
+            :status => :pending,
+            :pending_message => "unimplemented"
+          )
+        ])
+      end
+    end
+
+    describe "adding examples" do
+
+      it "allows adding an example using 'it'" do
+        group = RSpec.describe
+        group.it("should do something") { }
+        expect(group.examples.size).to eq(1)
+      end
+
+      it "exposes all examples at examples" do
+        group = RSpec.describe
+        group.it("should do something 1") { }
+        group.it("should do something 2") { }
+        group.it("should do something 3") { }
+        expect(group.examples.count).to eq(3)
+      end
+
+      it "maintains the example order" do
+        group = RSpec.describe
+        group.it("should 1") { }
+        group.it("should 2") { }
+        group.it("should 3") { }
+        expect(group.examples[0].description).to eq('should 1')
+        expect(group.examples[1].description).to eq('should 2')
+        expect(group.examples[2].description).to eq('should 3')
+      end
+
+    end
+
+    describe Object, "describing nested example_groups", :little_less_nested => 'yep' do
+
+      describe "A sample nested group", :nested_describe => "yep" do
+        it "sets the described class to the nearest described class" do |ex|
+          expect(ex.example_group.described_class).to eq(Object)
+        end
+
+        it "sets the description to 'A sample nested describe'" do |ex|
+          expect(ex.example_group.description).to eq('A sample nested group')
+        end
+
+        it "has top level metadata from the example_group and its parent groups" do |ex|
+          expect(ex.example_group.metadata).to include(:little_less_nested => 'yep', :nested_describe => 'yep')
+        end
+
+        it "exposes the parent metadata to the contained examples" do |ex|
+          expect(ex.metadata).to include(:little_less_nested => 'yep', :nested_describe => 'yep')
+        end
+      end
+
+    end
+
+    describe "#run_examples" do
+
+      let(:reporter) { double("reporter").as_null_object }
+
+      it "returns true if all examples pass" do
+        group = RSpec.describe('group') do
+          example('ex 1') { expect(1).to eq(1) }
+          example('ex 2') { expect(1).to eq(1) }
+        end
+        allow(group).to receive(:filtered_examples) { group.examples }
+        expect(group.run(reporter)).to be_truthy
+      end
+
+      it "returns false if any of the examples fail" do
+        group = RSpec.describe('group') do
+          example('ex 1') { expect(1).to eq(1) }
+          example('ex 2') { expect(1).to eq(2) }
+        end
+        allow(group).to receive(:filtered_examples) { group.examples }
+        expect(group.run(reporter)).to be_falsey
+      end
+
+      it "runs all examples, regardless of any of them failing" do
+        group = RSpec.describe('group') do
+          example('ex 1') { expect(1).to eq(2) }
+          example('ex 2') { expect(1).to eq(1) }
+        end
+        allow(group).to receive(:filtered_examples) { group.examples }
+        group.filtered_examples.each do |example|
+          expect(example).to receive(:run)
+        end
+        expect(group.run(reporter)).to be_falsey
+      end
+    end
+
+    describe "how instance variables are inherited" do
+      before(:all) do
+        @before_all_top_level = 'before_all_top_level'
+      end
+
+      before(:each) do
+        @before_each_top_level = 'before_each_top_level'
+      end
+
+      it "can access a before each ivar at the same level" do
+        expect(@before_each_top_level).to eq('before_each_top_level')
+      end
+
+      it "can access a before all ivar at the same level" do
+        expect(@before_all_top_level).to eq('before_all_top_level')
+      end
+
+      it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.8 do |ex|
+        expect(ex.example_group.before_context_ivars).to include('@before_all_top_level' => 'before_all_top_level')
+      end
+
+      it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.9 do |ex|
+        expect(ex.example_group.before_context_ivars).to include(:@before_all_top_level => 'before_all_top_level')
+      end
+
+      describe "but now I am nested" do
+        it "can access a parent example groups before each ivar at a nested level" do
+          expect(@before_each_top_level).to eq('before_each_top_level')
+        end
+
+        it "can access a parent example groups before all ivar at a nested level" do
+          expect(@before_all_top_level).to eq("before_all_top_level")
+        end
+
+        it "changes to before all ivars from within an example do not persist outside the current describe" do
+          @before_all_top_level = "ive been changed"
+        end
+
+        describe "accessing a before_all ivar that was changed in a parent example_group" do
+          it "does not have access to the modified version" do
+            expect(@before_all_top_level).to eq('before_all_top_level')
+          end
+        end
+      end
+
+    end
+
+    describe "ivars are not shared across examples" do
+      it "(first example)" do
+        @a = 1
+        expect(defined?(@b)).to be_falsey
+      end
+
+      it "(second example)" do
+        @b = 2
+        expect(defined?(@a)).to be_falsey
+      end
+    end
+
+
+    describe "#top_level_description" do
+      it "returns the description from the outermost example group" do
+        group = nil
+        RSpec.describe("top") do
+          context "middle" do
+            group = describe "bottom" do
+            end
+          end
+        end
+
+        expect(group.top_level_description).to eq("top")
+      end
+    end
+
+    describe "#run" do
+      let(:reporter) { double("reporter").as_null_object }
+
+      context "with fail_fast? => true" do
+        let(:group) do
+          group = RSpec.describe
+          allow(group).to receive(:fail_fast?) { true }
+          group
+        end
+
+        it "does not run examples after the failed example" do
+          examples_run = []
+          self.group.example('example 1') { examples_run << self }
+          self.group.example('example 2') { examples_run << self; fail; }
+          self.group.example('example 3') { examples_run << self }
+
+          self.group.run
+
+          expect(examples_run.length).to eq(2)
+        end
+
+        it "sets RSpec.world.wants_to_quit flag if encountering an exception in before(:all)" do
+          self.group.before(:all) { raise "error in before all" }
+          self.group.example("equality") { expect(1).to eq(2) }
+          expect(self.group.run).to be_falsey
+          expect(RSpec.world.wants_to_quit).to be_truthy
+        end
+      end
+
+      context "with RSpec.world.wants_to_quit=true" do
+        let(:group) { RSpec.describe }
+
+        before do
+          allow(RSpec.world).to receive(:wants_to_quit) { true }
+          allow(RSpec.world).to receive(:clear_remaining_example_groups)
+        end
+
+        it "returns without starting the group" do
+          expect(reporter).not_to receive(:example_group_started)
+          self.group.run(reporter)
+        end
+
+        context "at top level" do
+          it "purges remaining groups" do
+            expect(RSpec.world).to receive(:clear_remaining_example_groups)
+            self.group.run(reporter)
+          end
+        end
+
+        context "in a nested group" do
+          it "does not purge remaining groups" do
+            nested_group = self.group.describe
+            expect(RSpec.world).not_to receive(:clear_remaining_example_groups)
+            nested_group.run(reporter)
+          end
+        end
+      end
+
+      context "with all examples passing" do
+        it "returns true" do
+          group = RSpec.describe("something") do
+            it "does something" do
+              # pass
+            end
+            describe "nested" do
+              it "does something else" do
+                # pass
+              end
+            end
+          end
+
+          expect(group.run(reporter)).to be_truthy
+        end
+      end
+
+      context "with top level example failing" do
+        it "returns false" do
+          group = RSpec.describe("something") do
+            it "does something (wrong - fail)" do
+              raise "fail"
+            end
+            describe "nested" do
+              it "does something else" do
+                # pass
+              end
+            end
+          end
+
+          expect(group.run(reporter)).to be_falsey
+        end
+      end
+
+      context "with nested example failing" do
+        it "returns true" do
+          group = RSpec.describe("something") do
+            it "does something" do
+              # pass
+            end
+            describe "nested" do
+              it "does something else (wrong -fail)" do
+                raise "fail"
+              end
+            end
+          end
+
+          expect(group.run(reporter)).to be_falsey
+        end
+      end
+    end
+
+    %w[include_examples include_context].each do |name|
+      describe "##{name}" do
+        let(:group) { RSpec.describe }
+        before do
+          self.group.shared_examples "named this" do
+            example("does something") {}
+          end
+        end
+
+        it "includes the named examples" do
+          self.group.send(name, "named this")
+          expect(self.group.examples.first.description).to eq("does something")
+        end
+
+        it "raises a helpful error message when shared content is not found" do
+          expect do
+            self.group.send(name, "shared stuff")
+          end.to raise_error(ArgumentError, /Could not find .* "shared stuff"/)
+        end
+
+        it "leaves RSpec's thread metadata unchanged" do
+          expect {
+            self.group.send(name, "named this")
+          }.to avoid_changing(RSpec, :thread_local_metadata)
+        end
+
+        it "leaves RSpec's thread metadata unchanged, even when an error occurs during evaluation" do
+          expect {
+            self.group.send(name, "named this") do
+              raise "boom"
+            end
+          }.to raise_error("boom").and avoid_changing(RSpec, :thread_local_metadata)
+        end
+
+        it "passes parameters to the shared content" do
+          passed_params = {}
+          group = RSpec.describe
+
+          group.shared_examples "named this with params" do |param1, param2|
+            it("has access to the given parameters") do
+              passed_params[:param1] = param1
+              passed_params[:param2] = param2
+            end
+          end
+
+          group.send(name, "named this with params", :value1, :value2)
+          group.run
+
+          expect(passed_params).to eq({ :param1 => :value1, :param2 => :value2 })
+        end
+
+        it "adds shared instance methods to the group" do
+          group = RSpec.describe('fake group')
+          group.shared_examples "named this with params" do |param1|
+            def foo; end
+          end
+          group.send(name, "named this with params", :a)
+          expect(group.public_instance_methods.map{|m| m.to_s}).to include("foo")
+        end
+
+        it "evals the shared example group only once" do
+          eval_count = 0
+          group = RSpec.describe('fake group')
+          group.shared_examples("named this with params") { |p| eval_count += 1 }
+          group.send(name, "named this with params", :a)
+          expect(eval_count).to eq(1)
+        end
+
+        it "evals the block when given" do
+          key = "#{__FILE__}:#{__LINE__}"
+          group = RSpec.describe do
+            shared_examples(key) do
+              it("does something") do
+                expect(foo).to eq("bar")
+              end
+            end
+
+            send name, key do
+              def foo; "bar"; end
+            end
+          end
+          expect(group.run).to be_truthy
+        end
+      end
+    end
+
+    describe "#it_should_behave_like" do
+      it "creates a nested group" do
+        group = RSpec.describe('fake group')
+        group.shared_examples_for("thing") {}
+        group.it_should_behave_like("thing")
+        expect(group.children.count).to eq(1)
+      end
+
+      it "creates a nested group for a class" do
+        klass = Class.new
+        group = RSpec.describe('fake group')
+        group.shared_examples_for(klass) {}
+        group.it_should_behave_like(klass)
+        expect(group.children.count).to eq(1)
+      end
+
+      it "adds shared examples to nested group" do
+        group = RSpec.describe('fake group')
+        group.shared_examples_for("thing") do
+          it("does something")
+        end
+        shared_group = group.it_should_behave_like("thing")
+        expect(shared_group.examples.count).to eq(1)
+      end
+
+      it "adds shared instance methods to nested group" do
+        group = RSpec.describe('fake group')
+        group.shared_examples_for("thing") do
+          def foo; end
+        end
+        shared_group = group.it_should_behave_like("thing")
+        expect(shared_group.public_instance_methods.map{|m| m.to_s}).to include("foo")
+      end
+
+      it "adds shared class methods to nested group" do
+        group = RSpec.describe('fake group')
+        group.shared_examples_for("thing") do
+          def self.foo; end
+        end
+        shared_group = group.it_should_behave_like("thing")
+        expect(shared_group.methods.map{|m| m.to_s}).to include("foo")
+      end
+
+      it "passes parameters to the shared example group" do
+        passed_params = {}
+
+        group = RSpec.describe("group") do
+          shared_examples_for("thing") do |param1, param2|
+            it("has access to the given parameters") do
+              passed_params[:param1] = param1
+              passed_params[:param2] = param2
+            end
+          end
+
+          it_should_behave_like "thing", :value1, :value2
+        end
+
+        group.run
+
+        expect(passed_params).to eq({ :param1 => :value1, :param2 => :value2 })
+      end
+
+      it "adds shared instance methods to nested group" do
+        group = RSpec.describe('fake group')
+        group.shared_examples_for("thing") do |param1|
+          def foo; end
+        end
+        shared_group = group.it_should_behave_like("thing", :a)
+        expect(shared_group.public_instance_methods.map{|m| m.to_s}).to include("foo")
+      end
+
+      it "evals the shared example group only once" do
+        eval_count = 0
+        group = RSpec.describe('fake group')
+        group.shared_examples_for("thing") { |p| eval_count += 1 }
+        group.it_should_behave_like("thing", :a)
+        expect(eval_count).to eq(1)
+      end
+
+      context "given a block" do
+        it "evaluates the block in nested group" do
+          scopes = []
+          group = RSpec.describe("group") do
+            shared_examples_for("thing") do
+              it("gets run in the nested group") do
+                scopes << self.class
+              end
+            end
+            it_should_behave_like "thing" do
+              it("gets run in the same nested group") do
+                scopes << self.class
+              end
+            end
+          end
+          group.run
+
+          expect(scopes[0]).to be(scopes[1])
+        end
+      end
+
+      it "raises a helpful error message when shared context is not found" do
+        expect do
+          RSpec.describe do
+            it_should_behave_like "shared stuff"
+          end
+        end.to raise_error(ArgumentError,%q|Could not find shared examples "shared stuff"|)
+      end
+
+      it "leaves RSpec's thread metadata unchanged" do
+        expect {
+          RSpec.describe do
+            shared_examples_for("stuff") { }
+            it_should_behave_like "stuff"
+          end
+        }.to avoid_changing(RSpec, :thread_local_metadata)
+      end
+
+      it "leaves RSpec's thread metadata unchanged, even when an error occurs during evaluation" do
+        expect {
+          RSpec.describe do
+            shared_examples_for("stuff") { }
+            it_should_behave_like "stuff" do
+              raise "boom"
+            end
+          end
+        }.to raise_error("boom").and avoid_changing(RSpec, :thread_local_metadata)
+      end
+    end
+
+    it 'minimizes the number of methods that users could inadvertantly overwrite' do
+      rspec_core_methods = ExampleGroup.instance_methods -
+        RSpec::Matchers.instance_methods -
+        RSpec::Mocks::ExampleMethods.instance_methods -
+        Object.instance_methods -
+        ["singleton_class"]
+
+      # Feel free to expand this list if you intend to add another public API
+      # for users. RSpec internals should not add methods here, though.
+      expect(rspec_core_methods.map(&:to_sym)).to contain_exactly(
+        :described_class, :subject,
+        :is_expected, :should, :should_not,
+        :pending, :skip,
+        :setup_mocks_for_rspec, :teardown_mocks_for_rspec, :verify_mocks_for_rspec
+      )
+    end
+
+    it 'prevents defining nested isolated contexts' do
+      expect {
+        RSpec.describe do
+          describe {}
+          RSpec.describe {}
+        end
+      }.to raise_error(/not allowed/)
+    end
+
+    it 'prevents defining nested isolated shared contexts' do
+      expect {
+        RSpec.describe do
+          ExampleGroup.shared_examples("common functionality") {}
+        end
+      }.to raise_error(/not allowed/)
+    end
+
+    describe 'inspect output', :unless => RUBY_VERSION == '1.9.2' do
+      context 'when there is no inspect output provided' do
+        it "uses '(no description provided)' instead" do
+          expect(ExampleGroup.new.inspect).to eq('#<RSpec::Core::ExampleGroup (no description provided)>')
+        end
+      end
+
+      context 'when an example has a description' do
+        it 'includes description and location' do
+          an_example = nil
+
+          line = __LINE__ + 2
+          group = RSpec.describe 'SomeClass1' do
+            example 'an example' do
+              an_example = self
+            end
+          end
+
+          group.run
+
+          path = RSpec::Core::Metadata.relative_path(__FILE__)
+          expect(an_example.inspect).to eq("#<RSpec::ExampleGroups::SomeClass1 \"an example\" (#{path}:#{line})>")
+        end
+      end
+
+      context 'when an example does not have a description' do
+        it 'includes fallback description' do
+          an_example = nil
+
+          line = __LINE__ + 2
+          group = RSpec.describe 'SomeClass2' do
+            example do
+              an_example = self
+            end
+          end
+
+          group.run
+
+          path = RSpec::Core::Metadata.relative_path(__FILE__)
+          expect(an_example.inspect).to eq("#<RSpec::ExampleGroups::SomeClass2 \"example at #{path}:#{line}\">")
+        end
+      end
+
+      it 'handles before context hooks' do
+        a_before_hook = nil
+
+        group = RSpec.describe 'SomeClass3' do
+          before(:context) do
+            a_before_hook = self
+          end
+
+          example {}
+        end
+
+        group.run
+        expect(a_before_hook.inspect).to eq("#<RSpec::ExampleGroups::SomeClass3 before(:context) hook>")
+      end
+
+      it 'handles after context hooks' do
+        an_after_hook = nil
+
+        group = RSpec.describe 'SomeClass4' do
+          after(:context) do
+            an_after_hook = self
+          end
+
+          example {}
+        end
+
+        group.run
+        expect(an_after_hook.inspect).to eq("#<RSpec::ExampleGroups::SomeClass4 after(:context) hook>")
+      end
+
+      it "does not pollute an example's `inspect` output with the inspect ivar from `before(:context)`" do
+        inspect_output = nil
+
+        line = __LINE__ + 2
+        group = RSpec.describe do
+          example do
+            inspect_output = inspect
+          end
+
+          before(:context) {}
+        end
+
+        group.run
+
+        path = RSpec::Core::Metadata.relative_path(__FILE__)
+        expect(inspect_output).to end_with("\"example at #{path}:#{line}\">")
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/example_spec.rb b/rspec-core/spec/rspec/core/example_spec.rb
new file mode 100644
index 0000000..7fa62cb
--- /dev/null
+++ b/rspec-core/spec/rspec/core/example_spec.rb
@@ -0,0 +1,735 @@
+require 'pp'
+require 'stringio'
+
+RSpec.describe RSpec::Core::Example, :parent_metadata => 'sample' do
+
+  let(:example_group) do
+    RSpec.describe('group description')
+  end
+
+  let(:example_instance) do
+    example_group.example('example description') { }
+  end
+
+  it_behaves_like "metadata hash builder" do
+    def metadata_hash(*args)
+      example = example_group.example('example description', *args)
+      example.metadata
+    end
+  end
+
+  it "can be pretty printed" do
+    expect { ignoring_warnings { pp example_instance }}.to output(/RSpec::Core::Example/).to_stdout
+  end
+
+  describe "#exception" do
+    it "supplies the first exception raised, if any" do
+      RSpec.configuration.output_stream = StringIO.new
+
+      example = example_group.example { raise "first" }
+      example_group.after { raise "second" }
+      example_group.run
+      expect(example.exception.message).to eq("first")
+    end
+
+    it "returns nil if there is no exception" do
+      example = example_group.example('example') { }
+      example_group.run
+      expect(example.exception).to be_nil
+    end
+  end
+
+  describe "when there is an explicit description" do
+    context "when RSpec.configuration.format_docstrings is set to a block" do
+      it "formats the description using the block" do
+        RSpec.configuration.format_docstrings { |s| s.strip }
+        example = example_group.example(' an example with whitespace ') {}
+        example_group.run
+        expect(example.description).to eql('an example with whitespace')
+      end
+    end
+  end
+
+  describe "when there is no explicit description" do
+    def expect_with(*frameworks)
+      if frameworks.include?(:stdlib)
+        example_group.class_exec do
+          def assert(val)
+            raise "Expected #{val} to be true" unless val
+          end
+        end
+      end
+    end
+
+    context "when RSpec.configuration.format_docstrings is set to a block" do
+      it "formats the description using the block" do
+        RSpec.configuration.format_docstrings { |s| s.upcase }
+        example_group.example { }
+        example_group.run
+        pattern = /EXAMPLE AT #{relative_path(__FILE__).upcase}:#{__LINE__ - 2}/
+        expect(example_group.examples.first.description).to match(pattern)
+      end
+    end
+
+    context "when `expect_with :rspec` is configured" do
+      before(:each) { expect_with :rspec }
+
+      it "uses the matcher-generated description" do
+        example_group.example { expect(5).to eq(5) }
+        example_group.run
+        expect(example_group.examples.first.description).to eq("should eq 5")
+      end
+
+      it "uses the matcher-generated description in the full description" do
+        example_group.example { expect(5).to eq(5) }
+        example_group.run
+        expect(example_group.examples.first.full_description).to eq("group description should eq 5")
+      end
+
+      it "uses the file and line number if there is no matcher-generated description" do
+        example = example_group.example {}
+        example_group.run
+        expect(example.description).to match(/example at #{relative_path(__FILE__)}:#{__LINE__ - 2}/)
+      end
+
+      it "uses the file and line number if there is an error before the matcher" do
+        example = example_group.example { expect(5).to eq(5) }
+        example_group.before { raise }
+        example_group.run
+        expect(example.description).to match(/example at #{relative_path(__FILE__)}:#{__LINE__ - 3}/)
+      end
+
+      context "if the example is pending" do
+        it "still uses the matcher-generated description if a matcher ran" do
+          example = example_group.example { pending; expect(4).to eq(5) }
+          example_group.run
+          expect(example.description).to eq("should eq 5")
+        end
+
+        it "uses the file and line number of the example if no matcher ran" do
+          example = example_group.example { pending; fail }
+          example_group.run
+          expect(example.description).to match(/example at #{relative_path(__FILE__)}:#{__LINE__ - 2}/)
+        end
+      end
+
+      context "when an `after(:example)` hook raises an error" do
+        it 'still assigns the description' do
+          ex = nil
+
+          RSpec.describe do
+            ex = example { expect(2).to eq(2) }
+            after { raise "boom" }
+          end.run
+
+          expect(ex.description).to eq("should eq 2")
+        end
+      end
+
+      context "when the matcher's `description` method raises an error" do
+        description_line = __LINE__ + 3
+        RSpec::Matchers.define :matcher_with_failing_description do
+          match { true }
+          description { raise ArgumentError, "boom" }
+        end
+
+        it 'allows the example to pass and surfaces the failing description in the example description' do
+          ex = nil
+
+          RSpec.describe do
+            ex = example { expect(2).to matcher_with_failing_description }
+          end.run
+
+          expect(ex).to pass.and have_attributes(:description => a_string_including(
+            "example at #{ex.location}",
+            "ArgumentError",
+            "boom",
+            "#{__FILE__}:#{description_line}"
+          ))
+        end
+      end
+
+      context "when an `after(:example)` hook has an expectation" do
+        it "assigns the description based on the example's last expectation, ignoring the `after` expectation since it can apply to many examples" do
+          ex = nil
+
+          RSpec.describe do
+            ex = example { expect(nil).to be_nil }
+            after { expect(true).to eq(true) }
+          end.run
+
+          expect(ex).to pass.and have_attributes(:description => "should be nil")
+        end
+      end
+    end
+
+    context "when `expect_with :rspec, :stdlib` is configured" do
+      before(:each) { expect_with :rspec, :stdlib }
+
+      it "uses the matcher-generated description" do
+        example_group.example { expect(5).to eq(5) }
+        example_group.run
+        expect(example_group.examples.first.description).to eq("should eq 5")
+      end
+
+      it "uses the file and line number if there is no matcher-generated description" do
+        example = example_group.example {}
+        example_group.run
+        expect(example.description).to match(/example at #{relative_path(__FILE__)}:#{__LINE__ - 2}/)
+      end
+
+      it "uses the file and line number if there is an error before the matcher" do
+        example = example_group.example { expect(5).to eq(5) }
+        example_group.before { raise }
+        example_group.run
+        expect(example.description).to match(/example at #{relative_path(__FILE__)}:#{__LINE__ - 3}/)
+      end
+    end
+
+    context "when `expect_with :stdlib` is configured" do
+      before(:each) { expect_with :stdlib }
+
+      it "does not attempt to get the generated description from RSpec::Matchers" do
+        expect(RSpec::Matchers).not_to receive(:generated_description)
+        example_group.example { assert 5 == 5 }
+        example_group.run
+      end
+
+      it "uses the file and line number" do
+        example = example_group.example { assert 5 == 5 }
+        example_group.run
+        expect(example.description).to match(/example at #{relative_path(__FILE__)}:#{__LINE__ - 2}/)
+      end
+    end
+  end
+
+  describe "#described_class" do
+    it "returns the class (if any) of the outermost example group" do
+      expect(described_class).to eq(RSpec::Core::Example)
+    end
+  end
+
+  describe "accessing metadata within a running example" do
+    it "has a reference to itself when running" do |ex|
+      expect(ex.description).to eq("has a reference to itself when running")
+    end
+
+    it "can access the example group's top level metadata as if it were its own" do |ex|
+      expect(ex.example_group.metadata).to include(:parent_metadata => 'sample')
+      expect(ex.metadata).to include(:parent_metadata => 'sample')
+    end
+  end
+
+  describe "accessing options within a running example" do
+    it "can look up option values by key", :demo => :data do |ex|
+      expect(ex.metadata[:demo]).to eq(:data)
+    end
+  end
+
+  describe "#run" do
+    it "sets its reference to the example group instance to nil" do
+      group = RSpec.describe do
+        example('example') { expect(1).to eq(1) }
+      end
+      group.run
+      expect(group.examples.first.instance_variable_get("@example_group_instance")).to be_nil
+    end
+
+    it "generates a description before tearing down mocks in case a mock object is used in the description" do
+      group = RSpec.describe do
+        example { test = double('Test'); expect(test).to eq test }
+      end
+
+      expect(RSpec::Matchers).to receive(:generated_description).and_call_original.ordered
+      expect(RSpec::Mocks).to receive(:teardown).and_call_original.ordered
+
+      group.run
+    end
+
+    it "runs after(:each) when the example passes" do
+      after_run = false
+      group = RSpec.describe do
+        after(:each) { after_run = true }
+        example('example') { expect(1).to eq(1) }
+      end
+      group.run
+      expect(after_run).to be_truthy, "expected after(:each) to be run"
+    end
+
+    it "runs after(:each) when the example fails" do
+      after_run = false
+      group = RSpec.describe do
+        after(:each) { after_run = true }
+        example('example') { expect(1).to eq(2) }
+      end
+      group.run
+      expect(after_run).to be_truthy, "expected after(:each) to be run"
+    end
+
+    it "runs after(:each) when the example raises an Exception" do
+      after_run = false
+      group = RSpec.describe do
+        after(:each) { after_run = true }
+        example('example') { raise "this error" }
+      end
+      group.run
+      expect(after_run).to be_truthy, "expected after(:each) to be run"
+    end
+
+    context "with an after(:each) that raises" do
+      it "runs subsequent after(:each)'s" do
+        after_run = false
+        group = RSpec.describe do
+          after(:each) { after_run = true }
+          after(:each) { raise "FOO" }
+          example('example') { expect(1).to eq(1) }
+        end
+        group.run
+        expect(after_run).to be_truthy, "expected after(:each) to be run"
+      end
+
+      it "stores the exception" do
+        group = RSpec.describe
+        group.after(:each) { raise "FOO" }
+        example = group.example('example') { expect(1).to eq(1) }
+
+        group.run
+
+        expect(example.execution_result.exception.message).to eq("FOO")
+      end
+    end
+
+    it "wraps before/after(:each) inside around" do
+      results = []
+      group = RSpec.describe do
+        around(:each) do |e|
+          results << "around (before)"
+          e.run
+          results << "around (after)"
+        end
+        before(:each) { results << "before" }
+        after(:each) { results << "after" }
+        example { results << "example" }
+      end
+
+      group.run
+      expect(results).to eq([
+                          "around (before)",
+                          "before",
+                          "example",
+                          "after",
+                          "around (after)"
+                        ])
+    end
+
+    context "clearing ivars" do
+      it "sets ivars to nil to prep them for GC" do
+        group = RSpec.describe do
+          before(:all)  { @before_all  = :before_all }
+          before(:each) { @before_each = :before_each }
+          after(:each)  { @after_each = :after_each }
+          after(:all)   { @after_all  = :after_all }
+        end
+        group.example("does something") do
+          expect(@before_all).to eq(:before_all)
+          expect(@before_each).to eq(:before_each)
+        end
+        expect(group.run(double.as_null_object)).to be_truthy
+        group.new do |example|
+          %w[@before_all @before_each @after_each @after_all].each do |ivar|
+            expect(example.instance_variable_get(ivar)).to be_nil
+          end
+        end
+      end
+
+      it "does not impact the before_all_ivars which are copied to each example" do
+        group = RSpec.describe do
+          before(:all) { @before_all = "abc" }
+          example("first") { expect(@before_all).not_to be_nil }
+          example("second") { expect(@before_all).not_to be_nil }
+        end
+        expect(group.run).to be_truthy
+      end
+    end
+
+    context 'when the example raises an error' do
+      def run_and_capture_reported_message(group)
+        reported_msg = nil
+        # We can't use should_receive(:message).with(/.../) here,
+        # because if that fails, it would fail within our example-under-test,
+        # and since there's already two errors, it would just be reported again.
+        allow(RSpec.configuration.reporter).to receive(:message) { |msg| reported_msg = msg }
+        group.run
+        reported_msg
+      end
+
+      it "prints any around hook errors rather than silencing them" do
+        group = RSpec.describe do
+          around(:each) { |e| e.run; raise "around" }
+          example("e") { raise "example" }
+        end
+
+        message = run_and_capture_reported_message(group)
+        expect(message).to match(/An error occurred in an `around.* hook/i)
+      end
+
+      it "prints any after hook errors rather than silencing them" do
+        group = RSpec.describe do
+          after(:each) { raise "after" }
+          example("e") { raise "example" }
+        end
+
+        message = run_and_capture_reported_message(group)
+        expect(message).to match(/An error occurred in an after.* hook/i)
+      end
+
+      it "does not print mock expectation errors" do
+        group = RSpec.describe do
+          example do
+            foo = double
+            expect(foo).to receive(:bar)
+            raise "boom"
+          end
+        end
+
+        message = run_and_capture_reported_message(group)
+        expect(message).to be_nil
+      end
+
+      it "leaves a raised exception unmodified (GH-1103)" do
+        # set the backtrace, otherwise MRI will build a whole new object,
+        # and thus mess with our expectations. Rubinius and JRuby are not
+        # affected.
+        exception = StandardError.new
+        exception.set_backtrace([])
+
+        group = RSpec.describe do
+          example { raise exception.freeze }
+        end
+        group.run
+
+        actual = group.examples.first.execution_result.exception
+        expect(actual.__id__).to eq(exception.__id__)
+      end
+    end
+
+    context "with --dry-run" do
+      before { RSpec.configuration.dry_run = true }
+
+      it "does not execute any examples or hooks" do
+        executed = []
+
+        RSpec.configure do |c|
+          c.before(:each) { executed << :before_each_config }
+          c.before(:all)  { executed << :before_all_config }
+          c.after(:each)  { executed << :after_each_config }
+          c.after(:all)   { executed << :after_all_config }
+          c.around(:each) { |ex| executed << :around_each_config; ex.run }
+        end
+
+        group = RSpec.describe do
+          before(:all)  { executed << :before_all }
+          before(:each) { executed << :before_each }
+          after(:all)   { executed << :after_all }
+          after(:each)  { executed << :after_each }
+          around(:each) { |ex| executed << :around_each; ex.run }
+
+          example { executed << :example }
+
+          context "nested" do
+            before(:all)  { executed << :nested_before_all }
+            before(:each) { executed << :nested_before_each }
+            after(:all)   { executed << :nested_after_all }
+            after(:each)  { executed << :nested_after_each }
+            around(:each) { |ex| executed << :nested_around_each; ex.run }
+
+            example { executed << :nested_example }
+          end
+        end
+
+        group.run
+        expect(executed).to eq([])
+      end
+    end
+  end
+
+  describe "#pending" do
+    def expect_pending_result(example)
+      expect(example).to be_pending
+      expect(example.execution_result.status).to eq(:pending)
+      expect(example.execution_result.pending_message).to be
+    end
+
+    context "in the example" do
+      it "sets the example to pending" do
+        group = RSpec.describe do
+          example { pending; fail }
+        end
+        group.run
+        expect_pending_result(group.examples.first)
+      end
+
+      it "allows post-example processing in around hooks (see https://github.com/rspec/rspec-core/issues/322)" do
+        blah = nil
+        group = RSpec.describe do
+          around do |example|
+            example.run
+            blah = :success
+          end
+          example { pending }
+        end
+        group.run
+        expect(blah).to be(:success)
+      end
+
+      it 'sets the backtrace to the example definition so it can be located by the user' do
+        file = RSpec::Core::Metadata.relative_path(__FILE__)
+        expected = [file, __LINE__ + 2].map(&:to_s)
+        group = RSpec.describe do
+          example {
+            pending
+          }
+        end
+        group.run
+
+        actual = group.examples.first.exception.backtrace.first.split(':')[0..1]
+        expect(actual).to eq(expected)
+      end
+    end
+
+    context "in before(:each)" do
+      it "sets each example to pending" do
+        group = RSpec.describe do
+          before(:each) { pending }
+          example { fail }
+          example { fail }
+        end
+        group.run
+        expect_pending_result(group.examples.first)
+        expect_pending_result(group.examples.last)
+      end
+
+      it 'sets example to pending when failure occurs in before(:each)' do
+        group = RSpec.describe do
+          before(:each) { pending; fail }
+          example {}
+        end
+        group.run
+        expect_pending_result(group.examples.first)
+      end
+    end
+
+    context "in before(:all)" do
+      it "is forbidden" do
+        group = RSpec.describe do
+          before(:all) { pending }
+          example { fail }
+          example { fail }
+        end
+        group.run
+        expect(group.examples.first.exception).to be
+        expect(group.examples.first.exception.message).to \
+          match(/may not be used outside of examples/)
+      end
+
+      it "fails with an ArgumentError if a block is provided" do
+        group = RSpec.describe('group') do
+          before(:all) do
+            pending { :no_op }
+          end
+          example { fail }
+        end
+        example = group.examples.first
+        group.run
+        expect(example).to fail_with ArgumentError
+        expect(example.exception.message).to match(
+          /Passing a block within an example is now deprecated./
+        )
+      end
+    end
+
+    context "in around(:each)" do
+      it "sets the example to pending" do
+        group = RSpec.describe do
+          around(:each) { pending }
+          example { fail }
+        end
+        group.run
+        expect_pending_result(group.examples.first)
+      end
+
+      it 'sets example to pending when failure occurs in around(:each)' do
+        group = RSpec.describe do
+          around(:each) { pending; fail }
+          example {}
+        end
+        group.run
+        expect_pending_result(group.examples.first)
+      end
+    end
+
+    context "in after(:each)" do
+      it "sets each example to pending" do
+        group = RSpec.describe do
+          after(:each) { pending; fail }
+          example { }
+          example { }
+        end
+        group.run
+        expect_pending_result(group.examples.first)
+        expect_pending_result(group.examples.last)
+      end
+    end
+
+  end
+
+  describe "#skip" do
+    context "in the example" do
+      it "sets the example to skipped" do
+        group = RSpec.describe do
+          example { skip }
+        end
+        group.run
+        expect(group.examples.first).to be_skipped
+      end
+
+      it "allows post-example processing in around hooks (see https://github.com/rspec/rspec-core/issues/322)" do
+        blah = nil
+        group = RSpec.describe do
+          around do |example|
+            example.run
+            blah = :success
+          end
+          example { skip }
+        end
+        group.run
+        expect(blah).to be(:success)
+      end
+
+      context "with a message" do
+        it "sets the example to skipped with the provided message" do
+          group = RSpec.describe do
+            example { skip "lorem ipsum" }
+          end
+          group.run
+          expect(group.examples.first).to be_skipped_with("lorem ipsum")
+        end
+      end
+    end
+
+    context "in before(:each)" do
+      it "sets each example to skipped" do
+        group = RSpec.describe do
+          before(:each) { skip }
+          example {}
+          example {}
+        end
+        group.run
+        expect(group.examples.first).to be_skipped
+        expect(group.examples.last).to be_skipped
+      end
+    end
+
+    context "in before(:all)" do
+      it "sets each example to skipped" do
+        group = RSpec.describe do
+          before(:all) { skip("not done"); fail }
+          example {}
+          example {}
+        end
+        group.run
+        expect(group.examples.first).to be_skipped_with("not done")
+        expect(group.examples.last).to be_skipped_with("not done")
+      end
+    end
+
+    context "in around(:each)" do
+      it "sets the example to skipped" do
+        group = RSpec.describe do
+          around(:each) { skip }
+          example {}
+        end
+        group.run
+        expect(group.examples.first).to be_skipped
+      end
+    end
+  end
+
+  describe "timing" do
+    it "uses RSpec::Core::Time as to not be affected by changes to time in examples" do
+      reporter = double(:reporter).as_null_object
+      group = RSpec.describe
+      example = group.example
+      example.__send__ :start, reporter
+      allow(Time).to receive_messages(:now => Time.utc(2012, 10, 1))
+      example.__send__ :finish, reporter
+      expect(example.execution_result.run_time).to be < 0.2
+    end
+  end
+
+  it "does not interfere with per-example randomness when running examples in a random order" do
+    values = []
+
+    RSpec.configuration.order = :random
+
+    RSpec.describe do
+      # The bug was only triggered when the examples
+      # were in nested contexts; see https://github.com/rspec/rspec-core/pull/837
+      context { example { values << rand } }
+      context { example { values << rand } }
+    end.run
+
+    expect(values.uniq.count).to eq(2)
+  end
+
+  describe "optional block argument" do
+    it "contains the example" do |ex|
+      expect(ex).to be_an(RSpec::Core::Example)
+      expect(ex.description).to match(/contains the example/)
+    end
+  end
+
+  describe "setting the current example" do
+    it "sets RSpec.current_example to the example that is currently running" do
+      group = RSpec.describe("an example group")
+
+      current_examples = []
+      example1 = group.example("example 1") { current_examples << RSpec.current_example }
+      example2 = group.example("example 2") { current_examples << RSpec.current_example }
+
+      group.run
+      expect(current_examples).to eq([example1, example2])
+    end
+  end
+
+  describe "mock framework integration" do
+    it 'verifies mock expectations after each example' do
+      ex = nil
+
+      RSpec.describe do
+        let(:dbl) { double }
+        ex = example do
+          expect(dbl).to receive(:foo)
+        end
+      end.run
+
+      expect(ex).to fail_with(RSpec::Mocks::MockExpectationError)
+    end
+
+    it 'allows `after(:example)` hooks to satisfy mock expectations, since examples are not complete until their `after` hooks run' do
+      ex = nil
+
+      RSpec.describe do
+        let(:dbl) { double }
+
+        ex = example do
+          expect(dbl).to receive(:foo)
+        end
+
+        after { dbl.foo }
+      end.run
+
+      expect(ex).to pass
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/failed_example_notification_spec.rb b/rspec-core/spec/rspec/core/failed_example_notification_spec.rb
new file mode 100644
index 0000000..846b658
--- /dev/null
+++ b/rspec-core/spec/rspec/core/failed_example_notification_spec.rb
@@ -0,0 +1,23 @@
+module RSpec::Core::Notifications
+  RSpec.describe FailedExampleNotification do
+    before do
+      allow(RSpec.configuration).to receive(:color_enabled?).and_return(true)
+    end
+
+    it "uses the default color for the shared example backtrace line" do
+      example = nil
+      group = RSpec.describe "testing" do
+        shared_examples_for "a" do
+          example = it "fails" do
+            expect(1).to eq(2)
+          end
+        end
+        it_behaves_like "a"
+      end
+      group.run
+      fne = FailedExampleNotification.new(example)
+      lines = fne.colorized_message_lines
+      expect(lines).to include(match("\\e\\[37mShared Example Group:"))
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/filter_manager_spec.rb b/rspec-core/spec/rspec/core/filter_manager_spec.rb
new file mode 100644
index 0000000..7482246
--- /dev/null
+++ b/rspec-core/spec/rspec/core/filter_manager_spec.rb
@@ -0,0 +1,350 @@
+module RSpec::Core
+  RSpec.describe FilterManager do
+    def opposite(name)
+      name =~ /^in/ ? name.sub(/^(in)/,'ex') : name.sub(/^(ex)/,'in')
+    end
+
+    subject(:filter_manager) { FilterManager.new }
+    let(:inclusions) { filter_manager.inclusions }
+    let(:exclusions) { filter_manager.exclusions }
+
+    %w[include inclusions exclude exclusions].each_slice(2) do |name, type|
+      describe "##{name}" do
+        subject(:rules) { send(type).rules }
+        let(:opposite_rules) { send(opposite(type)).rules }
+
+        it "merges #{type}" do
+          filter_manager.send name, :foo => :bar
+          filter_manager.send name, :baz => :bam
+          expect(rules).to eq(:foo => :bar, :baz => :bam)
+        end
+
+        it "overrides previous #{type} with (via merge)" do
+          filter_manager.send name, :foo => 1
+          filter_manager.send name, :foo => 2
+          expect(rules).to eq(:foo => 2)
+        end
+
+        it "deletes matching opposites" do
+          filter_manager.exclusions.clear # defaults
+          filter_manager.send opposite(name), :foo => 1
+          filter_manager.send name, :foo => 2
+          expect(rules).to eq(:foo => 2)
+          expect(opposite_rules).to be_empty
+        end
+
+        if name == "include"
+          context "with :full_description" do
+            it "clears previous inclusions" do
+              filter_manager.include :foo => :bar
+              filter_manager.include :full_description => "value"
+              expect(rules).to eq(:full_description => "value")
+            end
+
+            it "clears previous exclusion" do
+              filter_manager.include :foo => :bar
+              filter_manager.include :full_description => "value"
+              expect(opposite_rules).to be_empty
+            end
+
+            it "does nothing when :full_description previously set" do
+              filter_manager.include :full_description => "a_value"
+              filter_manager.include :foo => :bar
+              expect(rules).to eq(:full_description => "a_value")
+            end
+          end
+        end
+      end
+
+      describe "##{name}_only" do
+        subject(:rules) { send(type).rules }
+        let(:opposite_rules) { send(opposite(type)).rules }
+
+        it "replaces existing #{type}" do
+          filter_manager.send name, :foo => 1, :bar => 2
+          filter_manager.send "#{name}_only", :foo => 3
+          expect(rules).to eq(:foo => 3)
+        end
+
+        it "deletes matching opposites" do
+          filter_manager.send opposite(name), :foo => 1
+          filter_manager.send "#{name}_only", :foo => 2
+          expect(rules).to eq(:foo => 2)
+          expect(opposite_rules).to be_empty
+        end
+      end
+
+      describe "##{name}_with_low_priority" do
+        subject(:rules) { send(type).rules }
+        let(:opposite_rules) { send(opposite(type)).rules }
+
+        it "ignores new #{type} if same key exists" do
+          filter_manager.send name, :foo => 1
+          filter_manager.send "#{name}_with_low_priority", :foo => 2
+          expect(rules).to eq(:foo => 1)
+        end
+
+        it "ignores new #{type} if same key exists in opposite" do
+          filter_manager.send opposite(name), :foo => 1
+          filter_manager.send "#{name}_with_low_priority", :foo => 1
+          expect(rules).to be_empty
+          expect(opposite_rules).to eq(:foo => 1)
+        end
+
+        it "keeps new #{type} if same key exists in opposite but values are different" do
+          filter_manager.send opposite(name), :foo => 1
+          filter_manager.send "#{name}_with_low_priority", :foo => 2
+          expect(rules).to eq(:foo => 2)
+          expect(opposite_rules).to eq(:foo => 1)
+        end
+      end
+    end
+
+    describe "#prune" do
+      def example_with(*args)
+        RSpec.describe("group", *args).example("example")
+      end
+
+      it "prefers location to exclusion filter" do
+        group = RSpec.describe("group")
+        included = group.example("include", :slow => true) {}
+        excluded = group.example("exclude") {}
+        filter_manager.add_location(__FILE__, [__LINE__ - 2])
+        filter_manager.exclude_with_low_priority :slow => true
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "still applies inclusion filters to examples from files with no location filters" do
+        group = RSpec.describe("group")
+        included_via_location = group.example("inc via location"); line = __LINE__
+        excluded_via_location = group.example("exc via location", :foo)
+
+        included_via_tag, excluded_via_tag = instance_eval <<-EOS, "some/other_spec.rb", 1
+          group = RSpec.describe("group")
+          [group.example("inc via tag", :foo), group.example("exc via tag")]
+        EOS
+
+        filter_manager.add_location(__FILE__, [line])
+        filter_manager.include_with_low_priority :foo => true
+
+        expect(filter_manager.prune([
+          included_via_location, excluded_via_location,
+          included_via_tag, excluded_via_tag
+        ]).map(&:description)).to eq([included_via_location, included_via_tag].map(&:description))
+      end
+
+      it "prefers location to exclusion filter on entire group" do
+        # We way want to change this behaviour in future, see:
+        # https://github.com/rspec/rspec-core/issues/779
+        group = RSpec.describe("group")
+        included = group.example("include", :slow => true) {}
+        excluded = example_with
+        filter_manager.add_location(__FILE__, [__LINE__ - 3])
+        filter_manager.exclude_with_low_priority :slow => true
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      context "with examples from multiple spec source files" do
+        it "applies exclusions only to examples defined in files with no location filters" do
+          group = RSpec.describe("group")
+          line = __LINE__ + 1
+          this_file_example = group.example("ex 1", :slow) { }
+
+          # Using eval in order to make ruby think this got defined in another file.
+          other_file_example = instance_eval "ex = nil; RSpec.describe('group') { ex = it('ex 2', :slow) { } }; ex", "some/external/file.rb", 1
+
+          filter_manager.exclude_with_low_priority :slow => true
+
+          expect {
+            filter_manager.add_location(__FILE__, [line])
+          }.to change {
+            filter_manager.prune([this_file_example, other_file_example]).map(&:description)
+          }.from([]).to([this_file_example.description])
+        end
+      end
+
+      it "prefers description to exclusion filter" do
+        group = RSpec.describe("group")
+        included = group.example("include", :slow => true) {}
+        excluded = group.example("exclude") {}
+        filter_manager.include(:full_description => /include/)
+        filter_manager.exclude_with_low_priority :slow => true
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "includes objects with tags matching inclusions" do
+        included = example_with({:foo => :bar})
+        excluded = example_with
+        filter_manager.include :foo => :bar
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "excludes objects with tags matching exclusions" do
+        included = example_with
+        excluded = example_with({:foo => :bar})
+        filter_manager.exclude :foo => :bar
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "prefers exclusion when matches previously set inclusion" do
+        included = example_with
+        excluded = example_with({:foo => :bar})
+        filter_manager.include :foo => :bar
+        filter_manager.exclude :foo => :bar
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "prefers inclusion when matches previously set exclusion" do
+        included = example_with({:foo => :bar})
+        excluded = example_with
+        filter_manager.exclude :foo => :bar
+        filter_manager.include :foo => :bar
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "prefers previously set inclusion when exclusion matches but has lower priority" do
+        included = example_with({:foo => :bar})
+        excluded = example_with
+        filter_manager.include :foo => :bar
+        filter_manager.exclude_with_low_priority :foo => :bar
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      it "prefers previously set exclusion when inclusion matches but has lower priority" do
+        included = example_with
+        excluded = example_with({:foo => :bar})
+        filter_manager.exclude :foo => :bar
+        filter_manager.include_with_low_priority :foo => :bar
+        expect(filter_manager.prune([included, excluded])).to eq([included])
+      end
+
+      context "with multiple inclusion filters" do
+        it 'includes objects that match any of them' do
+          examples = [
+            included_1 = example_with(:foo => true),
+            included_2 = example_with(:bar => true),
+                         example_with(:bazz => true)
+          ]
+
+          filter_manager.include :foo => true, :bar => true
+          expect(filter_manager.prune(examples)).to contain_exactly(included_1, included_2)
+        end
+      end
+    end
+
+    describe "#inclusions#description" do
+      subject(:description) { inclusions.description }
+
+      it 'cleans up the description' do
+        project_dir = File.expand_path('.')
+        expect(lambda { }.inspect).to include(project_dir)
+        expect(lambda { }.inspect).to include(' (lambda)') if RUBY_VERSION > '1.9'
+        expect(lambda { }.inspect).to include('0x')
+
+        filter_manager.include :foo => lambda { }
+
+        expect(description).not_to include(project_dir)
+        expect(description).not_to include(' (lambda)')
+        expect(description).not_to include('0x')
+      end
+    end
+
+    describe "#exclusions#description" do
+      subject(:description) { exclusions.description }
+
+      it 'cleans up the description' do
+        project_dir = File.expand_path('.')
+        expect(lambda { }.inspect).to include(project_dir)
+        expect(lambda { }.inspect).to include(' (lambda)') if RUBY_VERSION > '1.9'
+        expect(lambda { }.inspect).to include('0x')
+
+        filter_manager.exclude :foo => lambda { }
+
+        expect(description).not_to include(project_dir)
+        expect(description).not_to include(' (lambda)')
+        expect(description).not_to include('0x')
+      end
+
+      it 'returns `{}` when it only contains the default filters' do
+        expect(description).to eq({}.inspect)
+      end
+
+      it 'includes other filters' do
+        filter_manager.exclude :foo => :bar
+        expect(description).to eq({ :foo => :bar }.inspect)
+      end
+
+      it 'includes an overriden :if filter' do
+        allow(RSpec).to receive(:deprecate)
+        filter_manager.exclude :if => :custom_filter
+        expect(description).to eq({ :if => :custom_filter }.inspect)
+      end
+
+      it 'includes an overriden :unless filter' do
+        allow(RSpec).to receive(:deprecate)
+        filter_manager.exclude :unless => :custom_filter
+        expect(description).to eq({ :unless => :custom_filter }.inspect)
+      end
+    end
+
+    describe ":if and :unless ExclusionFilters" do
+      def example_with_metadata(metadata)
+        value = nil
+        RSpec.describe("group") do
+          value = example('arbitrary example', metadata)
+        end
+        value
+      end
+
+      def exclude?(example)
+        filter_manager.prune([example]).empty?
+      end
+
+      describe "the default :if filter" do
+        it "does not exclude a spec with  { :if => true } metadata" do
+          example = example_with_metadata(:if => true)
+          expect(exclude?(example)).to be_falsey
+        end
+
+        it "excludes a spec with  { :if => false } metadata" do
+          example = example_with_metadata(:if => false)
+          expect(exclude?(example)).to be_truthy
+        end
+
+        it "excludes a spec with  { :if => nil } metadata" do
+          example = example_with_metadata(:if => nil)
+          expect(exclude?(example)).to be_truthy
+        end
+
+        it "continues to be an exclusion even if exclusions are cleared" do
+          example = example_with_metadata(:if => false)
+          filter_manager.exclusions.clear
+          expect(exclude?(example)).to be_truthy
+        end
+      end
+
+      describe "the default :unless filter" do
+        it "excludes a spec with  { :unless => true } metadata" do
+          example = example_with_metadata(:unless => true)
+          expect(exclude?(example)).to be_truthy
+        end
+
+        it "does not exclude a spec with { :unless => false } metadata" do
+          example = example_with_metadata(:unless => false)
+          expect(exclude?(example)).to be_falsey
+        end
+
+        it "does not exclude a spec with { :unless => nil } metadata" do
+          example = example_with_metadata(:unless => nil)
+          expect(exclude?(example)).to be_falsey
+        end
+
+        it "continues to be an exclusion even if exclusions are cleared" do
+          example = example_with_metadata(:unless => true)
+          filter_manager.exclusions.clear
+          expect(exclude?(example)).to be_truthy
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/filterable_item_repository_spec.rb b/rspec-core/spec/rspec/core/filterable_item_repository_spec.rb
new file mode 100644
index 0000000..8171a43
--- /dev/null
+++ b/rspec-core/spec/rspec/core/filterable_item_repository_spec.rb
@@ -0,0 +1,202 @@
+module RSpec
+  module Core
+    RSpec.describe FilterableItemRepository, "#items_for" do
+      FilterableItem = Struct.new(:name)
+
+      def self.it_behaves_like_a_filterable_item_repo(&when_the_repo_has_items_with_metadata)
+        let(:repo)   { described_class.new(:any?) }
+        let(:item_1) { FilterableItem.new("Item 1") }
+        let(:item_2) { FilterableItem.new("Item 2") }
+        let(:item_3) { FilterableItem.new("Item 3") }
+        let(:item_4) { FilterableItem.new("Item 4") }
+
+        context "when the repository is empty" do
+          it 'returns an empty list' do
+            expect(repo.items_for(:foo => "bar")).to eq([])
+          end
+        end
+
+        shared_examples_for "adding items to the repository" do |add_method|
+          describe "adding items using `#{add_method}`" do
+            define_method :add_item do |*args|
+              repo.__send__ add_method, *args
+            end
+
+            context "when the repository has items that have no metadata" do
+              before do
+                add_item item_1, {}
+                add_item item_2, {}
+              end
+
+              it "returns those items, regardless of the provided argument" do
+                expect(repo.items_for({})).to contain_exactly(item_1, item_2)
+                expect(repo.items_for(:foo => "bar")).to contain_exactly(item_1, item_2)
+              end
+            end
+
+            context "when the repository has items that have metadata" do
+              before do
+                add_item item_1, :foo => "bar"
+                add_item item_2, :slow => true
+                add_item item_3, :foo => "bar"
+              end
+
+              it 'return an empty list when given empty metadata' do
+                expect(repo.items_for({})).to eq([])
+              end
+
+              it 'return an empty list when given metadata that matches no items' do
+                expect(repo.items_for(:slow => false, :foo => "bazz")).to eq([])
+              end
+
+              it 'returns matching items for the provided metadata' do
+                expect(repo.items_for(:slow => true)).to contain_exactly(item_2)
+                expect(repo.items_for(:foo => "bar")).to contain_exactly(item_1, item_3)
+                expect(repo.items_for(:slow => true, :foo => "bar")).to contain_exactly(item_1, item_2, item_3)
+              end
+
+              it 'returns the matching items in the correct order' do
+                expect(repo.items_for(:slow => true, :foo => "bar")).to eq items_in_expected_order
+              end
+
+              it 'ignores other metadata keys that are not related to the appended items' do
+                expect(repo.items_for(:slow => true, :other => "foo")).to contain_exactly(item_2)
+              end
+
+              it 'differentiates between an applicable key being missing and having an explicit `nil` value' do
+                add_item item_4, :bar => nil
+
+                expect(repo.items_for({})).to eq([])
+                expect(repo.items_for(:bar => nil)).to contain_exactly(item_4)
+              end
+
+              it 'returns the correct items when they are appended after a memoized lookup' do
+                expect {
+                  add_item item_4, :slow => true
+                }.to change { repo.items_for(:slow => true) }.
+                  from(a_collection_containing_exactly(item_2)).
+                  to(a_collection_containing_exactly(item_2, item_4))
+              end
+
+              let(:flip_proc) do
+                return_val = true
+                Proc.new { return_val.tap { |v| return_val = !v } }
+              end
+
+              context "with proc values" do
+                before do
+                  add_item item_4, { :include_it => flip_proc }
+                end
+
+                it 'evaluates the proc each time since the logic can return a different value each time' do
+                  expect(repo.items_for(:include_it => nil)).to contain_exactly(item_4)
+                  expect(repo.items_for(:include_it => nil)).to eq([])
+                  expect(repo.items_for(:include_it => nil)).to contain_exactly(item_4)
+                  expect(repo.items_for(:include_it => nil)).to eq([])
+                end
+              end
+
+              context "when initialized with the `:any?` predicate" do
+                let(:repo) { FilterableItemRepository::QueryOptimized.new(:any?) }
+
+                it 'matches against multi-entry items when any of the metadata entries match' do
+                  add_item item_4, :key_1 => "val_1", :key_2 => "val_2"
+
+                  expect(repo.items_for(:key_1 => "val_1")).to contain_exactly(item_4)
+                  expect(repo.items_for(:key_2 => "val_2")).to contain_exactly(item_4)
+                  expect(repo.items_for(:key_1 => "val_1", :key_2 => "val_2")).to contain_exactly(item_4)
+                end
+              end
+
+              context "when initialized with the `:all?` predicate" do
+                let(:repo) { FilterableItemRepository::QueryOptimized.new(:all?) }
+
+                it 'matches against multi-entry items when all of the metadata entries match' do
+                  add_item item_4, :key_1 => "val_1", :key_2 => "val_2"
+
+                  expect(repo.items_for(:key_1 => "val_1")).to eq([])
+                  expect(repo.items_for(:key_2 => "val_2")).to eq([])
+                  expect(repo.items_for(:key_1 => "val_1", :key_2 => "val_2")).to contain_exactly(item_4)
+                end
+              end
+
+              module_eval(&when_the_repo_has_items_with_metadata) if when_the_repo_has_items_with_metadata
+            end
+          end
+        end
+
+        it_behaves_like "adding items to the repository", :append do
+          let(:items_in_expected_order) { [item_1, item_2, item_3] }
+        end
+
+        it_behaves_like "adding items to the repository", :prepend do
+          let(:items_in_expected_order) { [item_3, item_2, item_1] }
+        end
+      end
+
+      describe FilterableItemRepository::UpdateOptimized do
+        it_behaves_like_a_filterable_item_repo
+      end
+
+      describe FilterableItemRepository::QueryOptimized do
+        it_behaves_like_a_filterable_item_repo do
+          describe "performance optimization" do
+            # NOTE: the specs in this context are potentially brittle because they are
+            # coupled to the implementation's usage of `MetadataFilter.apply?`. However,
+            # they demonstrate the perf optimization that was the reason we created
+            # this class, and thus have value in demonstrating the memoization is working
+            # properly and in documenting the reason the class exists in the first place.
+            # Still, if these prove to be brittle in the future, feel free to delete them since
+            # they are not concerned with externally visible behaviors.
+
+            it 'is optimized to check metadata filter application for a given pair of metadata hashes only once' do
+              # TODO: use mock expectations for this once https://github.com/rspec/rspec-mocks/pull/841 is fixed.
+              call_counts = track_metadata_filter_apply_calls
+
+              3.times do
+                expect(repo.items_for(:slow => true, :other => "foo")).to contain_exactly(item_2)
+              end
+
+              expect(call_counts[:slow => true]).to eq(1)
+            end
+
+            it 'ignores extraneous metadata keys when doing memoized lookups' do
+              # TODO: use mock expectations for this once https://github.com/rspec/rspec-mocks/pull/841 is fixed.
+              call_counts = track_metadata_filter_apply_calls
+
+              expect(repo.items_for(:slow => true, :other => "foo")).to contain_exactly(item_2)
+              expect(repo.items_for(:slow => true, :other => "bar")).to contain_exactly(item_2)
+              expect(repo.items_for(:slow => true, :goo => "bazz")).to contain_exactly(item_2)
+
+              expect(call_counts[:slow => true]).to eq(1)
+            end
+
+            context "when there are some proc keys" do
+              before do
+                add_item item_4, { :include_it => flip_proc }
+              end
+
+              it 'still performs memoization for metadata hashes that lack those keys' do
+                call_counts = track_metadata_filter_apply_calls
+
+                expect(repo.items_for(:slow => true, :other => "foo")).to contain_exactly(item_2)
+                expect(repo.items_for(:slow => true, :other => "foo")).to contain_exactly(item_2)
+
+                expect(call_counts[:slow => true]).to eq(1)
+              end
+            end
+
+            def track_metadata_filter_apply_calls
+              Hash.new(0).tap do |call_counts|
+                allow(MetadataFilter).to receive(:apply?).and_wrap_original do |original, predicate, item_meta, request_meta|
+                  call_counts[item_meta] += 1
+                  original.call(predicate, item_meta, request_meta)
+                end
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/base_text_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/base_text_formatter_spec.rb
new file mode 100644
index 0000000..bd5d476
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/base_text_formatter_spec.rb
@@ -0,0 +1,230 @@
+# encoding: utf-8
+require 'rspec/core/formatters/base_text_formatter'
+
+RSpec.describe RSpec::Core::Formatters::BaseTextFormatter do
+  include FormatterSupport
+
+  context "when closing the formatter", :isolated_directory => true do
+    it 'does not close an already closed output stream' do
+      output_to_close = File.new("./output_to_close", "w")
+      formatter = described_class.new(output_to_close)
+      output_to_close.close
+
+      expect { formatter.close(RSpec::Core::Notifications::NullNotification) }.not_to raise_error
+    end
+  end
+
+  describe "#dump_summary" do
+    it "with 0s outputs pluralized (excluding pending)" do
+      send_notification :dump_summary, summary_notification(0, [], [], [], 0)
+      expect(output.string).to match("0 examples, 0 failures")
+    end
+
+    it "with 1s outputs singular (including pending)" do
+      send_notification :dump_summary, summary_notification(0, examples(1), examples(1), examples(1), 0)
+      expect(output.string).to match("1 example, 1 failure, 1 pending")
+    end
+
+    it "with 2s outputs pluralized (including pending)" do
+      send_notification :dump_summary, summary_notification(2, examples(2), examples(2), examples(2), 0)
+      expect(output.string).to match("2 examples, 2 failures, 2 pending")
+    end
+
+    it "includes command to re-run each failed example" do
+      example_group = RSpec.describe("example group") do
+        it("fails") { fail }
+      end
+      line = __LINE__ - 2
+
+      expect(output_from_running example_group).to include("rspec #{RSpec::Core::Metadata::relative_path("#{__FILE__}:#{line}")} # example group fails")
+    end
+
+    context "for an example defined in an file required by the user rather than loaded by rspec" do
+      it "looks through ancestor metadata to find a workable re-run command" do
+        line = __LINE__ + 1
+        example_group = RSpec.describe("example group") do
+          # Using eval in order to make it think this got defined in an external file.
+          instance_eval "it('fails') { fail }", "some/external/file.rb", 1
+        end
+
+        expect(output_from_running example_group).to include("rspec #{RSpec::Core::Metadata::relative_path("#{__FILE__}:#{line}")} # example group fails")
+      end
+    end
+
+    def output_from_running(example_group)
+      allow(RSpec.configuration).to receive(:loaded_spec_files) { [File.expand_path(__FILE__)].to_set }
+      example_group.run(reporter)
+      examples = example_group.examples
+      send_notification :dump_summary, summary_notification(1, examples, examples, [], 0)
+      output.string
+    end
+  end
+
+  describe "#dump_failures" do
+    let(:group) { RSpec.describe("group name") }
+
+    before { allow(RSpec.configuration).to receive(:color_enabled?) { false } }
+
+    def run_all_and_dump_failures
+      group.run(reporter)
+      send_notification :dump_failures, failed_examples_notification
+    end
+
+    it "preserves formatting" do
+      group.example("example name") { expect("this").to eq("that") }
+
+      run_all_and_dump_failures
+
+      expect(output.string).to match(/group name example name/m)
+      expect(output.string).to match(/(\s+)expected: \"that\"\n\1     got: \"this\"/m)
+    end
+
+    context "with an exception without a message" do
+      it "does not throw NoMethodError" do
+        exception_without_message = Exception.new()
+        allow(exception_without_message).to receive(:message) { nil }
+        group.example("example name") { raise exception_without_message }
+        expect { run_all_and_dump_failures }.not_to raise_error
+      end
+
+      it "preserves ancestry" do
+        example = group.example("example name") { raise "something" }
+        run_all_and_dump_failures
+        expect(example.example_group.parent_groups.size).to eq 1
+      end
+    end
+
+    context "with an exception that has an exception instance as its message" do
+      it "does not raise NoMethodError" do
+        gonzo_exception = RuntimeError.new
+        allow(gonzo_exception).to receive(:message) { gonzo_exception }
+        group.example("example name") { raise gonzo_exception }
+        expect { run_all_and_dump_failures }.not_to raise_error
+      end
+    end
+
+    context "with an instance of an anonymous exception class" do
+      it "substitutes '(anonymous error class)' for the missing class name" do
+        exception = Class.new(StandardError).new
+        group.example("example name") { raise exception }
+        run_all_and_dump_failures
+        expect(output.string).to include('(anonymous error class)')
+      end
+    end
+
+    context "with an exception class other than RSpec" do
+      it "does not show the error class" do
+        group.example("example name") { raise NameError.new('foo') }
+        run_all_and_dump_failures
+        expect(output.string).to match(/NameError/m)
+      end
+    end
+
+    if String.method_defined?(:encoding)
+      context "with an exception that has a differently encoded message" do
+        it "runs without encountering an encoding exception" do
+          group.example("Mixing encodings, e.g. UTF-8: © and Binary") { raise "Error: \xC2\xA9".force_encoding("ASCII-8BIT") }
+          run_all_and_dump_failures
+          expect(output.string).to match(/RuntimeError:\n\s+Error: \?\?/m) # ?? because the characters dont encode properly
+        end
+      end
+    end
+
+    context "with a failed expectation (rspec-expectations)" do
+      it "does not show the error class" do
+        group.example("example name") { expect("this").to eq("that") }
+        run_all_and_dump_failures
+        expect(output.string).not_to match(/RSpec/m)
+      end
+    end
+
+    context "with a failed message expectation (rspec-mocks)" do
+      it "does not show the error class" do
+        group.example("example name") { expect("this").to receive("that") }
+        run_all_and_dump_failures
+        expect(output.string).not_to match(/RSpec/m)
+      end
+    end
+
+    %w[ include_examples it_should_behave_like ].each do |inclusion_method|
+      context "for #shared_examples included using #{inclusion_method}" do
+        it 'outputs the name and location' do
+          group.shared_examples 'foo bar' do
+            it("example name") { expect("this").to eq("that") }
+          end
+
+          line = __LINE__.next
+          group.__send__(inclusion_method, 'foo bar')
+
+          run_all_and_dump_failures
+
+          expect(output.string.lines).to include(a_string_ending_with(
+            'Shared Example Group: "foo bar" called from ' +
+              "#{RSpec::Core::Metadata.relative_path(__FILE__)}:#{line}\n"
+          ))
+        end
+
+        context 'that contains nested example groups' do
+          it 'outputs the name and location' do
+            group.shared_examples 'foo bar' do
+              describe 'nested group' do
+                it("example name") { expect("this").to eq("that") }
+              end
+            end
+
+            line = __LINE__.next
+            group.__send__(inclusion_method, 'foo bar')
+
+            run_all_and_dump_failures
+
+            expect(output.string.lines).to include(a_string_ending_with(
+              'Shared Example Group: "foo bar" called from ' +
+                "./spec/rspec/core/formatters/base_text_formatter_spec.rb:#{line}\n"
+            ))
+          end
+        end
+
+        context "that contains shared group nesting" do
+          it 'includes each inclusion location in the output' do
+            group.shared_examples "inner" do
+              example { expect(1).to eq(2) }
+            end
+
+            inner_line = __LINE__ + 2
+            group.shared_examples "outer" do
+              __send__(inclusion_method, "inner")
+            end
+
+            outer_line = __LINE__ + 1
+            group.__send__(inclusion_method, 'outer')
+
+            run_all_and_dump_failures
+
+            expect(output.string.lines.grep(/Shared Example Group/)).to match [
+              a_string_ending_with(
+                'Shared Example Group: "inner" called from ' +
+                  "./spec/rspec/core/formatters/base_text_formatter_spec.rb:#{inner_line}\n"
+              ),
+              a_string_ending_with(
+                'Shared Example Group: "outer" called from ' +
+                  "./spec/rspec/core/formatters/base_text_formatter_spec.rb:#{outer_line}\n"
+              ),
+            ]
+          end
+        end
+      end
+    end
+  end
+
+  describe "custom_colors" do
+    it "uses the custom success color" do
+      RSpec.configure do |config|
+        config.color = true
+        config.tty = true
+        config.success_color = :cyan
+      end
+      send_notification :dump_summary, summary_notification(0, examples(1), [], [], 0)
+      expect(output.string).to include("\e[36m")
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/console_codes_spec.rb b/rspec-core/spec/rspec/core/formatters/console_codes_spec.rb
new file mode 100644
index 0000000..04a9c7d
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/console_codes_spec.rb
@@ -0,0 +1,64 @@
+require 'rspec/core/formatters/console_codes'
+
+RSpec.describe "RSpec::Core::Formatters::ConsoleCodes" do
+  let(:console_codes) { RSpec::Core::Formatters::ConsoleCodes }
+
+  describe "#console_code_for(code_or_symbol)" do
+    context "when given a VT100 integer code" do
+      it "returns the code" do
+        expect(console_codes.console_code_for(32)).to eq 32
+      end
+    end
+
+    context "when given a symbolic name" do
+      it "returns the code" do
+        expect(console_codes.console_code_for(:green)).to eq 32
+      end
+    end
+
+    context "when given an rspec code" do
+      it "returns the console code" do
+        RSpec.configuration.success_color = :blue # blue is 34
+        expect(console_codes.console_code_for(:success)).to eq 34
+      end
+    end
+
+    context "when given a nonexistant code" do
+      it "returns the code for white" do
+        expect(console_codes.console_code_for(:octarine)).to eq 37
+      end
+    end
+  end
+
+  describe "#wrap" do
+    before do
+      allow(RSpec.configuration).to receive(:color_enabled?) { true }
+    end
+
+    context "when given a VT100 integer code" do
+      it "formats the text with it" do
+        expect(console_codes.wrap('abc', 32)).to eq "\e[32mabc\e[0m"
+      end
+    end
+
+    context "when given a symbolic color name" do
+      it "translates it to the correct integer code and formats the text with it" do
+        expect(console_codes.wrap('abc', :green)).to eq "\e[32mabc\e[0m"
+      end
+    end
+
+    context "when given an rspec code" do
+      it "returns the console code" do
+        RSpec.configuration.success_color = :blue # blue is 34
+        expect(console_codes.wrap('abc', :success)).to eq "\e[34mabc\e[0m"
+      end
+    end
+
+
+    context "when given :bold" do
+      it "formats the text as bold" do
+        expect(console_codes.wrap('abc', :bold)).to eq "\e[1mabc\e[0m"
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/deprecation_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/deprecation_formatter_spec.rb
new file mode 100644
index 0000000..122eb51
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/deprecation_formatter_spec.rb
@@ -0,0 +1,230 @@
+require 'rspec/core/reporter'
+require 'rspec/core/formatters/deprecation_formatter'
+require 'tempfile'
+
+module RSpec::Core::Formatters
+  RSpec.describe DeprecationFormatter do
+    include FormatterSupport
+
+    let(:summary_stream) { StringIO.new }
+
+    def notification(hash)
+      ::RSpec::Core::Notifications::DeprecationNotification.from_hash(hash)
+    end
+
+    before do
+      setup_reporter deprecation_stream, summary_stream
+    end
+
+    describe "#deprecation" do
+
+      context "with a File deprecation_stream", :slow do
+        let(:deprecation_stream) { File.open("#{Dir.tmpdir}/deprecation_summary_example_output", "w+") }
+
+        it "prints a message if provided, ignoring other data" do
+          send_notification :deprecation, notification(:message => "this message", :deprecated => "x", :replacement => "y", :call_site => "z")
+          deprecation_stream.rewind
+          expect(deprecation_stream.read).to eq "this message\n"
+        end
+
+        it "surrounds multiline messages in fenceposts" do
+          multiline_message = <<-EOS.gsub(/^\s+\|/, '')
+            |line one
+            |line two
+          EOS
+          send_notification :deprecation, notification(:message => multiline_message)
+          deprecation_stream.rewind
+
+          expected = <<-EOS.gsub(/^\s+\|/, '')
+            |--------------------------------------------------------------------------------
+            |line one
+            |line two
+            |--------------------------------------------------------------------------------
+          EOS
+          expect(deprecation_stream.read).to eq expected
+        end
+
+        it "includes the method" do
+          send_notification :deprecation, notification(:deprecated => "i_am_deprecated")
+          deprecation_stream.rewind
+          expect(deprecation_stream.read).to match(/i_am_deprecated is deprecated/)
+        end
+
+        it "includes the replacement" do
+          send_notification :deprecation, notification(:replacement => "use_me")
+          deprecation_stream.rewind
+          expect(deprecation_stream.read).to match(/Use use_me instead/)
+        end
+
+        it "includes the call site if provided" do
+          send_notification :deprecation, notification(:call_site => "somewhere")
+          deprecation_stream.rewind
+          expect(deprecation_stream.read).to match(/Called from somewhere/)
+        end
+      end
+
+      context "with an IO deprecation stream" do
+        let(:deprecation_stream) { StringIO.new }
+
+        it "prints nothing" do
+          5.times { send_notification :deprecation, notification(:deprecated => 'i_am_deprecated') }
+          expect(deprecation_stream.string).to eq ""
+        end
+      end
+    end
+
+    describe "#deprecation_summary" do
+      let(:summary)   { double }
+
+      context "with a File deprecation_stream", :slow do
+        let(:deprecation_stream) { File.open("#{Dir.tmpdir}/deprecation_summary_example_output", "w") }
+
+        it "prints a count of the deprecations" do
+          send_notification :deprecation, notification(:deprecated => 'i_am_deprecated')
+          send_notification :deprecation_summary, null_notification
+          expect(summary_stream.string).to match(/1 deprecation logged to .*deprecation_summary_example_output/)
+        end
+
+        it "pluralizes the reported deprecation count for more than one deprecation" do
+          send_notification :deprecation, notification(:deprecated => 'i_am_deprecated')
+          send_notification :deprecation, notification(:deprecated => 'i_am_deprecated_also')
+          send_notification :deprecation_summary, null_notification
+          expect(summary_stream.string).to match(/2 deprecations/)
+        end
+
+        it "is not printed when there are no deprecations" do
+          send_notification :deprecation_summary, null_notification
+          expect(summary_stream.string).to eq ""
+        end
+
+        it 'uses synchronized/non-buffered output to work around odd duplicate output behavior we have observed' do
+          expect {
+            send_notification :deprecation, notification(:deprecated => 'foo')
+          }.to change { deprecation_stream.sync }.from(false).to(true)
+        end
+
+        it 'does not print duplicate messages' do
+          3.times { send_notification :deprecation, notification(:deprecated => 'foo') }
+          send_notification :deprecation_summary, null_notification
+
+          expect(summary_stream.string).to match(/1 deprecation/)
+          expect(File.read(deprecation_stream.path)).to eq("foo is deprecated.\n#{DeprecationFormatter::RAISE_ERROR_CONFIG_NOTICE}")
+        end
+
+        it "can handle when the stream is reopened to a system stream", :unless => RSpec::Support::OS.windows? do
+          send_notification :deprecation, notification(:deprecated => 'foo')
+          deprecation_stream.reopen(IO.for_fd(IO.sysopen('/dev/null', "w+")))
+          send_notification :deprecation_summary, null_notification
+        end
+      end
+
+      context "with an Error deprecation_stream" do
+        let(:deprecation_stream) { DeprecationFormatter::RaiseErrorStream.new }
+
+        it 'prints a summary of the number of deprecations found' do
+          expect { send_notification :deprecation, notification(:deprecated => 'foo') }.to raise_error(RSpec::Core::DeprecationError)
+          send_notification :deprecation_summary, null_notification
+
+          expect(summary_stream.string).to eq("\n1 deprecation found.\n")
+        end
+
+        it 'pluralizes the count when it is greater than 1' do
+          expect { send_notification :deprecation, notification(:deprecated => 'foo') }.to raise_error(RSpec::Core::DeprecationError)
+          expect { send_notification :deprecation, notification(:deprecated => 'bar') }.to raise_error(RSpec::Core::DeprecationError)
+
+          send_notification :deprecation_summary, null_notification
+
+          expect(summary_stream.string).to eq("\n2 deprecations found.\n")
+        end
+      end
+
+      context "with an IO deprecation_stream" do
+        let(:deprecation_stream) { StringIO.new }
+
+        it "groups similar deprecations together" do
+          send_notification :deprecation, notification(:deprecated => 'i_am_deprecated', :call_site => "foo.rb:1")
+          send_notification :deprecation, notification(:deprecated => 'i_am_a_different_deprecation')
+          send_notification :deprecation, notification(:deprecated => 'i_am_deprecated', :call_site => "foo.rb:2")
+          send_notification :deprecation_summary, null_notification
+
+          expected = <<-EOS.gsub(/^\s+\|/, '')
+            |
+            |Deprecation Warnings:
+            |
+            |i_am_a_different_deprecation is deprecated.
+            |
+            |i_am_deprecated is deprecated. Called from foo.rb:1.
+            |i_am_deprecated is deprecated. Called from foo.rb:2.
+            |
+            |#{DeprecationFormatter::RAISE_ERROR_CONFIG_NOTICE}
+          EOS
+          expect(deprecation_stream.string).to eq expected.chomp
+        end
+
+        it "limits the deprecation warnings after 3 calls" do
+          5.times { |i| send_notification :deprecation, notification(:deprecated => 'i_am_deprecated', :call_site => "foo.rb:#{i + 1}") }
+          send_notification :deprecation_summary, null_notification
+          expected = <<-EOS.gsub(/^\s+\|/, '')
+            |
+            |Deprecation Warnings:
+            |
+            |i_am_deprecated is deprecated. Called from foo.rb:1.
+            |i_am_deprecated is deprecated. Called from foo.rb:2.
+            |i_am_deprecated is deprecated. Called from foo.rb:3.
+            |Too many uses of deprecated 'i_am_deprecated'. #{DeprecationFormatter::DEPRECATION_STREAM_NOTICE}
+            |
+            |#{DeprecationFormatter::RAISE_ERROR_CONFIG_NOTICE}
+          EOS
+          expect(deprecation_stream.string).to eq expected.chomp
+        end
+
+        it "limits :message deprecation warnings with different callsites after 3 calls" do
+          5.times do |n|
+            message = "This is a long string with some callsite info: /path/#{n}/to/some/file.rb:2#{n}3.  And some more stuff can come after."
+            send_notification :deprecation, notification(:message => message)
+          end
+          send_notification :deprecation_summary, null_notification
+          expected = <<-EOS.gsub(/^\s+\|/, '')
+            |
+            |Deprecation Warnings:
+            |
+            |This is a long string with some callsite info: /path/0/to/some/file.rb:203.  And some more stuff can come after.
+            |This is a long string with some callsite info: /path/1/to/some/file.rb:213.  And some more stuff can come after.
+            |This is a long string with some callsite info: /path/2/to/some/file.rb:223.  And some more stuff can come after.
+            |Too many similar deprecation messages reported, disregarding further reports. #{DeprecationFormatter::DEPRECATION_STREAM_NOTICE}
+            |
+            |#{DeprecationFormatter::RAISE_ERROR_CONFIG_NOTICE}
+          EOS
+          expect(deprecation_stream.string).to eq expected.chomp
+        end
+
+        it "prints the true deprecation count to the summary_stream" do
+          5.times { |i| send_notification :deprecation, notification(:deprecated => 'i_am_deprecated', :call_site => "foo.rb:#{i + 1}") }
+          5.times do |n|
+            send_notification :deprecation, notification(:message => "callsite info: /path/#{n}/to/some/file.rb:2#{n}3.  And some more stuff")
+          end
+          send_notification :deprecation_summary, null_notification
+          expect(summary_stream.string).to match(/10 deprecation warnings total/)
+        end
+
+        it 'does not print duplicate messages' do
+          3.times { send_notification :deprecation, notification(:deprecated => 'foo') }
+          send_notification :deprecation_summary, null_notification
+
+          expect(summary_stream.string).to match(/1 deprecation/)
+
+          expected = <<-EOS.gsub(/^\s+\|/, '')
+            |
+            |Deprecation Warnings:
+            |
+            |foo is deprecated.
+            |
+            |#{DeprecationFormatter::RAISE_ERROR_CONFIG_NOTICE}
+          EOS
+
+          expect(deprecation_stream.string).to eq expected.chomp
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/documentation_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/documentation_formatter_spec.rb
new file mode 100644
index 0000000..43eac1b
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/documentation_formatter_spec.rb
@@ -0,0 +1,110 @@
+require 'rspec/core/formatters/documentation_formatter'
+
+module RSpec::Core::Formatters
+  RSpec.describe DocumentationFormatter do
+    include FormatterSupport
+
+    before do
+      send_notification :start, start_notification(2)
+      allow(formatter).to receive(:color_enabled?).and_return(false)
+    end
+
+    def execution_result(values)
+      RSpec::Core::Example::ExecutionResult.new.tap do |er|
+        values.each { |name, value| er.__send__(:"#{name}=", value) }
+      end
+    end
+
+    it "numbers the failures" do
+      send_notification :example_failed, example_notification( double("example 1",
+               :description => "first example",
+               :execution_result => execution_result(:status => :failed, :exception => Exception.new)
+              ))
+      send_notification :example_failed, example_notification( double("example 2",
+               :description => "second example",
+               :execution_result => execution_result(:status => :failed, :exception => Exception.new)
+              ))
+
+      expect(output.string).to match(/first example \(FAILED - 1\)/m)
+      expect(output.string).to match(/second example \(FAILED - 2\)/m)
+    end
+
+    it "represents nested group using hierarchy tree" do
+      group = RSpec.describe("root")
+      context1 = group.describe("context 1")
+      context1.example("nested example 1.1"){}
+      context1.example("nested example 1.2"){}
+
+      context11 = context1.describe("context 1.1")
+      context11.example("nested example 1.1.1"){}
+      context11.example("nested example 1.1.2"){}
+
+      context2 = group.describe("context 2")
+      context2.example("nested example 2.1"){}
+      context2.example("nested example 2.2"){}
+
+      group.run(reporter)
+
+      expect(output.string).to eql("
+root
+  context 1
+    nested example 1.1
+    nested example 1.2
+    context 1.1
+      nested example 1.1.1
+      nested example 1.1.2
+  context 2
+    nested example 2.1
+    nested example 2.2
+")
+    end
+
+    it "strips whitespace for each row" do
+      group = RSpec.describe(" root ")
+      context1 = group.describe(" nested ")
+      context1.example(" example 1 ") {}
+      context1.example(" example 2 ", :pending => true){ fail }
+      context1.example(" example 3 ") { fail }
+
+      group.run(reporter)
+
+      expect(output.string).to eql("
+root
+  nested
+    example 1
+    example 2 (PENDING: No reason given)
+    example 3 (FAILED - 1)
+")
+    end
+
+    # The backrace is slightly different on JRuby so we skip there.
+    it 'produces the expected full output', :unless => RUBY_PLATFORM == 'java' do
+      output = run_example_specs_with_formatter("doc")
+      output.gsub!(/ +$/, '') # strip trailing whitespace
+
+      expect(output).to eq(<<-EOS.gsub(/^\s+\|/, ''))
+        |
+        |pending spec with no implementation
+        |  is pending (PENDING: Not yet implemented)
+        |
+        |pending command with block format
+        |  with content that would fail
+        |    is pending (PENDING: No reason given)
+        |  with content that would pass
+        |    fails (FAILED - 1)
+        |
+        |passing spec
+        |  passes
+        |
+        |failing spec
+        |  fails (FAILED - 2)
+        |
+        |a failing spec with odd backtraces
+        |  fails with a backtrace that has no file (FAILED - 3)
+        |  fails with a backtrace containing an erb file (FAILED - 4)
+        |
+        |#{expected_summary_output_for_example_specs}
+      EOS
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/helpers_spec.rb b/rspec-core/spec/rspec/core/formatters/helpers_spec.rb
new file mode 100644
index 0000000..6fe5085
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/helpers_spec.rb
@@ -0,0 +1,103 @@
+require 'rspec/core/formatters/helpers'
+
+RSpec.describe RSpec::Core::Formatters::Helpers do
+  helper = described_class
+
+  describe "format duration" do
+    context '< 1' do
+      it "returns '0.xxxxx seconds' formatted string" do
+        expect(helper.format_duration(0.123456)).to eq("0.12346 seconds")
+      end
+    end
+
+    context '> 1 and < 60' do
+      it "returns 'xx.xx seconds' formatted string" do
+        expect(helper.format_duration(45.51)).to eq("45.51 seconds")
+      end
+    end
+
+    context '> 60 and < 120' do
+      it "returns 'x minute xx.xx seconds' formatted string" do
+        expect(helper.format_duration(70.14)).to eq("1 minute 10.14 seconds")
+      end
+    end
+
+    context '> 120 and < 300' do
+      it "returns 'x minutes xx.x seconds' formatted string" do
+        expect(helper.format_duration(135.14)).to eq("2 minutes 15.1 seconds")
+      end
+    end
+
+    context '> 300' do
+      it "returns 'x minutes xx seconds' formatted string" do
+        expect(helper.format_duration(335.14)).to eq("5 minutes 35 seconds")
+      end
+    end
+
+    context '= 61' do
+      it "returns 'x minute x second' formatted string" do
+        expect(helper.format_duration(61)).to eq("1 minute 1 second")
+      end
+    end
+
+    context '= 1' do
+      it "returns 'x second' formatted string" do
+        expect(helper.format_duration(1)).to eq("1 second")
+      end
+    end
+
+    context 'with mathn loaded' do
+      include MathnIntegrationSupport
+
+      it "returns 'x minutes xx.x seconds' formatted string", :slow do
+        with_mathn_loaded do
+          expect(helper.format_duration(133.7)).to eq("2 minutes 13.7 seconds")
+        end
+      end
+    end
+  end
+
+  describe "format seconds" do
+    it "uses passed in precision if specified unless result is 0" do
+      expect(helper.format_seconds(0.01234, 2)).to eq("0.01")
+    end
+
+    context "sub second times" do
+      it "returns 5 digits of precision" do
+        expect(helper.format_seconds(0.000006)).to eq("0.00001")
+      end
+
+      it "strips off trailing zeroes beyond sub-second precision" do
+        expect(helper.format_seconds(0.020000)).to eq("0.02")
+      end
+
+      context "0" do
+        it "strips off trailing zeroes" do
+          expect(helper.format_seconds(0.00000000001)).to eq("0")
+        end
+      end
+
+      context "> 1" do
+        it "strips off trailing zeroes" do
+          expect(helper.format_seconds(1.00000000001)).to eq("1")
+        end
+      end
+    end
+
+    context "second and greater times" do
+
+      it "returns 2 digits of precision" do
+        expect(helper.format_seconds(50.330340)).to eq("50.33")
+      end
+
+      it "returns human friendly elasped time" do
+        expect(helper.format_seconds(50.1)).to eq("50.1")
+        expect(helper.format_seconds(5)).to eq("5")
+        expect(helper.format_seconds(5.0)).to eq("5")
+      end
+
+    end
+  end
+
+
+end
diff --git a/rspec-core/spec/rspec/core/formatters/html_formatted.html b/rspec-core/spec/rspec/core/formatters/html_formatted.html
new file mode 100644
index 0000000..9c3b4cd
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/html_formatted.html
@@ -0,0 +1,373 @@
+<html lang="en">
+<head>
+<title>RSpec results</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta http-equiv="Expires" content="-1">
+<meta http-equiv="Pragma" content="no-cache">
+<style type="text/css">
+  body {
+    margin: 0;
+    padding: 0;
+    background: #fff;
+    font-size: 80%;
+  }
+  </style>
+<script type="text/javascript">
+    // <![CDATA[
+
+function addClass(element_id, classname) {
+  document.getElementById(element_id).className += (" " + classname);
+}
+
+function removeClass(element_id, classname) {
+  var elem = document.getElementById(element_id);
+  var classlist = elem.className.replace(classname,'');
+  elem.className = classlist;
+}
+
+function moveProgressBar(percentDone) {
+  document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+
+function makeRed(element_id) {
+  removeClass(element_id, 'passed');
+  removeClass(element_id, 'not_implemented');
+  addClass(element_id,'failed');
+}
+
+function makeYellow(element_id) {
+  var elem = document.getElementById(element_id);
+  if (elem.className.indexOf("failed") == -1) {  // class doesn't includes failed
+    if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
+      removeClass(element_id, 'passed');
+      addClass(element_id,'not_implemented');
+    }
+  }
+}
+
+function apply_filters() {
+  var passed_filter = document.getElementById('passed_checkbox').checked;
+  var failed_filter = document.getElementById('failed_checkbox').checked;
+  var pending_filter = document.getElementById('pending_checkbox').checked;
+
+  assign_display_style("example passed", passed_filter);
+  assign_display_style("example failed", failed_filter);
+  assign_display_style("example not_implemented", pending_filter);
+
+  assign_display_style_for_group("example_group passed", passed_filter);
+  assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter);
+  assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
+}
+
+function get_display_style(display_flag) {
+  var style_mode = 'none';
+  if (display_flag == true) {
+    style_mode = 'block';
+  }
+  return style_mode;
+}
+
+function assign_display_style(classname, display_flag) {
+  var style_mode = get_display_style(display_flag);
+  var elems = document.getElementsByClassName(classname)
+  for (var i=0; i<elems.length;i++) {
+    elems[i].style.display = style_mode;
+  }
+}
+
+function assign_display_style_for_group(classname, display_flag, subgroup_flag) {
+  var display_style_mode = get_display_style(display_flag);
+  var subgroup_style_mode = get_display_style(subgroup_flag);
+  var elems = document.getElementsByClassName(classname)
+  for (var i=0; i<elems.length;i++) {
+    var style_mode = display_style_mode;
+    if ((display_flag != subgroup_flag) && (elems[i].getElementsByTagName('dt')[0].innerHTML.indexOf(", ") != -1)) {
+      elems[i].style.display = subgroup_style_mode;
+    } else {
+      elems[i].style.display = display_style_mode;
+    }
+  }
+}
+
+    // ]]>
+  </script><style type="text/css">
+#rspec-header {
+  background: #65C400; color: #fff; height: 4em;
+}
+
+.rspec-report h1 {
+  margin: 0px 10px 0px 10px;
+  padding: 10px;
+  font-family: "Lucida Grande", Helvetica, sans-serif;
+  font-size: 1.8em;
+  position: absolute;
+}
+
+#label {
+  float:left;
+}
+
+#display-filters {
+  float:left;
+  padding: 28px 0 0 40%;
+  font-family: "Lucida Grande", Helvetica, sans-serif;
+}
+
+#summary {
+  float:right;
+  padding: 5px 10px;
+  font-family: "Lucida Grande", Helvetica, sans-serif;
+  text-align: right;
+}
+
+#summary p {
+  margin: 0 0 0 2px;
+}
+
+#summary #totals {
+  font-size: 1.2em;
+}
+
+.example_group {
+  margin: 0 10px 5px;
+  background: #fff;
+}
+
+dl {
+  margin: 0; padding: 0 0 5px;
+  font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+  padding: 3px;
+  background: #65C400;
+  color: #fff;
+  font-weight: bold;
+}
+
+dd {
+  margin: 5px 0 5px 5px;
+  padding: 3px 3px 3px 18px;
+}
+
+dd .duration {
+  padding-left: 5px;
+  text-align: right;
+  right: 0px;
+  float:right;
+}
+
+dd.example.passed {
+  border-left: 5px solid #65C400;
+  border-bottom: 1px solid #65C400;
+  background: #DBFFB4; color: #3D7700;
+}
+
+dd.example.not_implemented {
+  border-left: 5px solid #FAF834;
+  border-bottom: 1px solid #FAF834;
+  background: #FCFB98; color: #131313;
+}
+
+dd.example.pending_fixed {
+  border-left: 5px solid #0000C2;
+  border-bottom: 1px solid #0000C2;
+  color: #0000C2; background: #D3FBFF;
+}
+
+dd.example.failed {
+  border-left: 5px solid #C20000;
+  border-bottom: 1px solid #C20000;
+  color: #C20000; background: #FFFBD3;
+}
+
+
+dt.not_implemented {
+  color: #000000; background: #FAF834;
+}
+
+dt.pending_fixed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+dt.failed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+
+#rspec-header.not_implemented {
+  color: #000000; background: #FAF834;
+}
+
+#rspec-header.pending_fixed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+#rspec-header.failed {
+  color: #FFFFFF; background: #C40D0D;
+}
+
+
+.backtrace {
+  color: #000;
+  font-size: 12px;
+}
+
+a {
+  color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+  font-size: 12px;
+  font-family: monospace;
+  color: white;
+  background-color: black;
+  padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+  width: 75px;
+  padding: 0.1em 1em 0.2em 0;
+  color: #000000;
+  background-color: #FFFBD3;
+}
+
+  </style>
+</head>
+<body>
+<div class="rspec-report">
+
+<div id="rspec-header">
+  <div id="label">
+    <h1>RSpec Code Examples</h1>
+  </div>
+
+  <div id="display-filters">
+    <input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked onchange="apply_filters()" value="1"><label for="passed_checkbox">Passed</label>
+    <input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked onchange="apply_filters()" value="2"><label for="failed_checkbox">Failed</label>
+    <input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked onchange="apply_filters()" value="3"><label for="pending_checkbox">Pending</label>
+  </div>
+
+  <div id="summary">
+    <p id="totals"> </p>
+    <p id="duration"> </p>
+  </div>
+</div>
+
+
+<div class="results">
+<div id="div_group_1" class="example_group passed">
+  <dl style="margin-left: 0px;">
+<dt id="example_group_1" class="passed">pending spec with no implementation</dt>
+    <script type="text/javascript">makeYellow('rspec-header');</script><script type="text/javascript">makeYellow('div_group_1');</script><script type="text/javascript">makeYellow('example_group_1');</script><script type="text/javascript">moveProgressBar('14.2');</script><dd class="example not_implemented"><span class="not_implemented_spec_name">is pending (PENDING: Not yet implemented)</span></dd>
+  </dl>
+</div>
+<div id="div_group_2" class="example_group passed">
+  <dl style="margin-left: 0px;">
+<dt id="example_group_2" class="passed">pending command with block format</dt>
+  </dl>
+</div>
+<div id="div_group_3" class="example_group passed">
+  <dl style="margin-left: 15px;">
+<dt id="example_group_3" class="passed">with content that would fail</dt>
+    <script type="text/javascript">makeYellow('rspec-header');</script><script type="text/javascript">makeYellow('div_group_3');</script><script type="text/javascript">makeYellow('example_group_3');</script><script type="text/javascript">moveProgressBar('28.5');</script><dd class="example not_implemented"><span class="not_implemented_spec_name">is pending (PENDING: No reason given)</span></dd>
+  </dl>
+</div>
+<div id="div_group_4" class="example_group passed">
+  <dl style="margin-left: 15px;">
+<dt id="example_group_4" class="passed">with content that would pass</dt>
+    <script type="text/javascript">makeRed('rspec-header');</script><script type="text/javascript">makeRed('div_group_4');</script><script type="text/javascript">makeRed('example_group_4');</script><script type="text/javascript">moveProgressBar('42.8');</script><dd class="example pending_fixed">
+      <span class="failed_spec_name">fails</span>
+      <span class="duration">n.nnnns</span>
+      <div class="failure" id="failure_1">
+        <div class="message"><pre>Expected example to fail since it is pending, but it passed.</pre></div>
+        <div class="backtrace"><pre>./spec/rspec/core/resources/formatter_specs.rb:16</pre></div>
+    <pre class="ruby"><code><span class="linenum">14</span>
+<span class="linenum">15</span>  context <span class="string"><span class="delimiter">"</span><span class="content">with content that would pass</span><span class="delimiter">"</span></span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">16</span>    it <span class="string"><span class="delimiter">"</span><span class="content">fails</span><span class="delimiter">"</span></span> <span class="keyword">do</span></span>
+<span class="linenum">17</span>      pending
+<span class="linenum">18</span>      expect(<span class="integer">1</span>).to eq(<span class="integer">1</span>)</code></pre>
+      </div>
+    </dd>
+  </dl>
+</div>
+<div id="div_group_5" class="example_group passed">
+  <dl style="margin-left: 0px;">
+<dt id="example_group_5" class="passed">passing spec</dt>
+    <script type="text/javascript">moveProgressBar('57.1');</script><dd class="example passed">
+<span class="passed_spec_name">passes</span><span class="duration">n.nnnns</span>
+</dd>
+  </dl>
+</div>
+<div id="div_group_6" class="example_group passed">
+  <dl style="margin-left: 0px;">
+<dt id="example_group_6" class="passed">failing spec</dt>
+    <script type="text/javascript">makeRed('div_group_6');</script><script type="text/javascript">makeRed('example_group_6');</script><script type="text/javascript">moveProgressBar('71.4');</script><dd class="example failed">
+      <span class="failed_spec_name">fails</span>
+      <span class="duration">n.nnnns</span>
+      <div class="failure" id="failure_2">
+        <div class="message"><pre>
+expected: 2
+     got: 1
+
+(compared using ==)
+</pre></div>
+        <div class="backtrace"><pre>./spec/rspec/core/resources/formatter_specs.rb:31</pre></div>
+    <pre class="ruby"><code><span class="linenum">29</span><span class="constant">RSpec</span>.describe <span class="string"><span class="delimiter">"</span><span class="content">failing spec</span><span class="delimiter">"</span></span> <span class="keyword">do</span>
+<span class="linenum">30</span>  it <span class="string"><span class="delimiter">"</span><span class="content">fails</span><span class="delimiter">"</span></span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">31</span>    expect(<span class="integer">1</span>).to eq(<span class="integer">2</span>)</span>
+<span class="linenum">32</span>  <span class="keyword">end</span>
+<span class="linenum">33</span><span class="keyword">end</span></code></pre>
+      </div>
+    </dd>
+  </dl>
+</div>
+<div id="div_group_7" class="example_group passed">
+  <dl style="margin-left: 0px;">
+<dt id="example_group_7" class="passed">a failing spec with odd backtraces</dt>
+    <script type="text/javascript">makeRed('div_group_7');</script><script type="text/javascript">makeRed('example_group_7');</script><script type="text/javascript">moveProgressBar('85.7');</script><dd class="example failed">
+      <span class="failed_spec_name">fails with a backtrace that has no file</span>
+      <span class="duration">n.nnnns</span>
+      <div class="failure" id="failure_3">
+        <div class="message"><pre>foo</pre></div>
+        <div class="backtrace"><pre>./spec/rspec/core/resources/formatter_specs.rb:39</pre></div>
+    <pre class="ruby"><code><span class="linenum">-1</span><span class="comment"># Couldn't get snippet for (erb)</span></code></pre>
+      </div>
+    </dd>
+    <script type="text/javascript">moveProgressBar('100.0');</script><dd class="example failed">
+      <span class="failed_spec_name">fails with a backtrace containing an erb file</span>
+      <span class="duration">n.nnnns</span>
+      <div class="failure" id="failure_4">
+        <div class="message"><pre>Exception</pre></div>
+        <div class="backtrace"><pre></pre></div>
+    <pre class="ruby"><code><span class="linenum">-1</span><span class="comment"># Couldn't get snippet for /foo.html.erb</span></code></pre>
+      </div>
+    </dd>
+  </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>n.nnnn seconds</strong>";</script><script type="text/javascript">document.getElementById('totals').innerHTML = "7 examples, 4 failures, 2 pending";</script>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/rspec-core/spec/rspec/core/formatters/html_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/html_formatter_spec.rb
new file mode 100644
index 0000000..255c29e
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/html_formatter_spec.rb
@@ -0,0 +1,113 @@
+# encoding: utf-8
+require 'rspec/core/formatters/html_formatter'
+
+# For some reason we get load errors when loading nokogiri on AppVeyor
+# on Ruby 2.1.  On 1.9.3 it works just fine. No idea why.
+require 'nokogiri' unless ENV['APPVEYOR'] && RUBY_VERSION.to_f >= 2.1
+
+module RSpec
+  module Core
+    module Formatters
+      RSpec.describe HtmlFormatter, :failing_on_appveyor => (RUBY_VERSION.to_f >= 2.1) do
+        include FormatterSupport
+
+        let(:root) { File.expand_path("#{File.dirname(__FILE__)}/../../../..") }
+        let(:expected_file) do
+          "#{File.dirname(__FILE__)}/html_formatted.html"
+        end
+
+        let(:generated_html) do
+          html = run_example_specs_with_formatter('html')
+
+          actual_doc = Nokogiri::HTML(html, &:noblanks)
+          actual_doc.css("div.backtrace pre").each do |elem|
+            # This is to minimize churn on backtrace lines that we do not
+            # assert on anyway.
+            backtrace = elem.inner_html.lines.
+              select {|e| e =~ /formatter_specs\.rb/ }.
+              map {|x| x.chomp.split(":")[0..1].join(':') }.
+              join("\n")
+
+            elem.inner_html = backtrace
+          end
+          actual_doc.inner_html
+        end
+
+        let(:expected_html) do
+          File.read(expected_file)
+        end
+
+        before do
+          allow(RSpec.configuration).to receive(:load_spec_files) do
+            RSpec.configuration.files_to_run.map {|f| load File.expand_path(f) }
+          end
+        end
+
+        # Uncomment this group temporarily in order to overwrite the expected
+        # with actual.  Use with care!!!
+        describe "file generator", :if => ENV['GENERATE'] do
+          it "generates a new comparison file" do
+            Dir.chdir(root) do
+              File.open(expected_file, 'w') {|io| io.write(generated_html)}
+            end
+          end
+        end
+
+        def extract_backtrace_from(doc)
+          doc.search("div.backtrace").
+            collect {|e| e.at("pre").inner_html}.
+            collect {|e| e.split("\n")}.flatten.
+            select  {|e| e =~ /formatter_specs\.rb/}
+        end
+
+        describe 'produced HTML', :if => RUBY_VERSION <= '2.0.0' do
+          # Rubies before 2 are a wild west of different outputs, and it's not
+          # worth the effort to maintain accurate fixtures for all of them.
+          # Since we are verifying fixtures on other rubies, if this code at
+          # least runs we can be reasonably confident the output is right since
+          # behaviour variances that we care about across versions is neglible.
+          it 'is present' do
+            expect(generated_html).to be
+          end
+        end
+
+        describe 'produced HTML', :slow, :if => RUBY_VERSION >= '2.0.0' do
+          def build_and_verify_formatter_output
+            Dir.chdir(root) do
+              actual_doc = Nokogiri::HTML(generated_html, &:noblanks)
+              actual_backtraces = extract_backtrace_from(actual_doc)
+              actual_doc.css("div.backtrace").remove
+
+              expected_doc = Nokogiri::HTML(expected_html, &:noblanks)
+              expected_backtraces = extract_backtrace_from(expected_doc)
+              expected_doc.search("div.backtrace").remove
+
+              expect(actual_doc.inner_html).to eq(expected_doc.inner_html)
+
+              expected_backtraces.each_with_index do |expected_line, i|
+                expected_path, expected_line_number, expected_suffix = expected_line.split(':')
+                actual_path, actual_line_number, actual_suffix = actual_backtraces[i].split(':')
+
+                expect(File.expand_path(actual_path)).to eq(File.expand_path(expected_path))
+                expect(actual_line_number).to eq(expected_line_number)
+                expect(actual_suffix).to eq(expected_suffix)
+              end
+            end
+          end
+
+          it "is identical to the one we designed manually", :pending => (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby') do
+            build_and_verify_formatter_output
+          end
+
+          context 'with mathn loaded' do
+            include MathnIntegrationSupport
+
+            it "is identical to the one we designed manually", :slow, :pending => (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby') do
+              with_mathn_loaded { build_and_verify_formatter_output }
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/json_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/json_formatter_spec.rb
new file mode 100644
index 0000000..4e42215
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/json_formatter_spec.rb
@@ -0,0 +1,182 @@
+require 'rspec/core/formatters/json_formatter'
+require 'json'
+require 'rspec/core/reporter'
+
+# todo, someday:
+# it "lists the groups (describe and context) separately"
+# it "includes full 'execution_result'"
+# it "relativizes backtrace paths"
+# it "includes profile information (implements dump_profile)"
+# it "shows the pending message if one was given"
+# it "shows the seed if run was randomized"
+# it "lists pending specs that were fixed"
+RSpec.describe RSpec::Core::Formatters::JsonFormatter do
+  include FormatterSupport
+
+  it "outputs json (brittle high level functional test)" do
+    group = RSpec.describe("one apiece") do
+      it("succeeds") { expect(1).to eq 1 }
+      it("fails") { fail "eek" }
+      it("pends") { pending "world peace"; fail "eek" }
+    end
+    succeeding_line = __LINE__ - 4
+    failing_line = __LINE__ - 4
+    pending_line = __LINE__ - 4
+
+    now = Time.now
+    allow(Time).to receive(:now).and_return(now)
+    reporter.report(2) do |r|
+      group.run(r)
+    end
+
+    # grab the actual backtrace -- kind of a cheat
+    examples = formatter.output_hash[:examples]
+    failing_backtrace = examples[1][:exception][:backtrace]
+    this_file = relative_path(__FILE__)
+
+    expected = {
+      :examples => [
+        {
+          :description => "succeeds",
+          :full_description => "one apiece succeeds",
+          :status => "passed",
+          :file_path => this_file,
+          :line_number => succeeding_line,
+          :run_time => formatter.output_hash[:examples][0][:run_time]
+        },
+        {
+          :description => "fails",
+          :full_description => "one apiece fails",
+          :status => "failed",
+          :file_path => this_file,
+          :line_number => failing_line,
+          :run_time => formatter.output_hash[:examples][1][:run_time],
+          :exception => {
+            :class     => "RuntimeError",
+            :message   => "eek",
+            :backtrace => failing_backtrace
+          }
+        },
+        {
+          :description => "pends",
+          :full_description => "one apiece pends",
+          :status => "pending",
+          :file_path => this_file,
+          :line_number => pending_line,
+          :run_time => formatter.output_hash[:examples][2][:run_time]
+        },
+      ],
+      :summary => {
+        :duration => formatter.output_hash[:summary][:duration],
+        :example_count => 3,
+        :failure_count => 1,
+        :pending_count => 1,
+      },
+      :summary_line => "3 examples, 1 failure, 1 pending"
+    }
+    expect(formatter.output_hash).to eq expected
+    expect(output.string).to eq expected.to_json
+  end
+
+  describe "#stop" do
+    it "adds all examples to the output hash" do
+      send_notification :stop, stop_notification
+      expect(formatter.output_hash[:examples]).not_to be_nil
+    end
+  end
+
+  describe "#close" do
+    it "outputs the results as a JSON string" do
+      expect(output.string).to eq ""
+      send_notification :close, null_notification
+      expect(output.string).to eq("{}")
+    end
+  end
+
+  describe "#message" do
+    it "adds a message to the messages list" do
+      send_notification :message, message_notification("good job")
+      expect(formatter.output_hash[:messages]).to eq ["good job"]
+    end
+  end
+
+  describe "#dump_summary" do
+    it "adds summary info to the output hash" do
+      send_notification :dump_summary, summary_notification(1.0, examples(10), examples(3), examples(4), 0)
+      expect(formatter.output_hash[:summary]).to include(
+        :duration => 1.0, :example_count => 10, :failure_count => 3,
+        :pending_count => 4
+      )
+      summary_line = formatter.output_hash[:summary_line]
+      expect(summary_line).to eq "10 examples, 3 failures, 4 pending"
+    end
+  end
+
+  describe "#dump_profile", :slow do
+
+    def profile *groups
+      groups.each { |group| group.run(reporter) }
+      examples = groups.map(&:examples).flatten
+      send_notification :dump_profile, profile_notification(0.5, examples, 10)
+    end
+
+    before do
+      formatter
+      config.profile_examples = 10
+    end
+
+    context "with one example group" do
+      before do
+        profile( RSpec.describe("group") do
+          example("example") { }
+        end)
+      end
+
+      it "names the example" do
+        expect(formatter.output_hash[:profile][:examples].first[:full_description]).to eq("group example")
+      end
+
+      it "provides example execution time" do
+        expect(formatter.output_hash[:profile][:examples].first[:run_time]).not_to be_nil
+      end
+
+      it "doesn't profile a single example group" do
+        expect(formatter.output_hash[:profile][:groups]).to be_empty
+      end
+
+      it "has the summary of profile information" do
+        expect(formatter.output_hash[:profile].keys).to match_array([:examples, :groups, :slowest, :total])
+      end
+    end
+
+    context "with multiple example groups", :slow do
+      before do
+        example_clock = class_double(RSpec::Core::Time, :now => RSpec::Core::Time.now + 0.5)
+
+        group1 = RSpec.describe("slow group") do
+          example("example") do |example|
+            # make it look slow without actually taking up precious time
+            example.clock = example_clock
+          end
+        end
+        group2 = RSpec.describe("fast group") do
+          example("example 1") { }
+          example("example 2") { }
+        end
+        profile group1, group2
+      end
+
+      it "provides the slowest example groups" do
+        expect(formatter.output_hash).not_to be_empty
+      end
+
+      it "provides information" do
+        expect(formatter.output_hash[:profile][:groups].first.keys).to match_array([:total_time, :count, :description, :average, :location])
+      end
+
+      it "ranks the example groups by average time" do
+        expect(formatter.output_hash[:profile][:groups].first[:description]).to eq("slow group")
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/profile_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/profile_formatter_spec.rb
new file mode 100644
index 0000000..ee53ce3
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/profile_formatter_spec.rb
@@ -0,0 +1,98 @@
+require 'rspec/core/formatters/profile_formatter'
+
+RSpec.describe RSpec::Core::Formatters::ProfileFormatter do
+  include FormatterSupport
+
+  def profile *groups
+    groups.each { |group| group.run(reporter) }
+    examples = groups.map(&:examples).flatten
+    total_time = examples.map { |e| e.execution_result.run_time }.inject(&:+)
+    send_notification :dump_profile, profile_notification(total_time, examples, 10)
+  end
+
+  describe "#dump_profile", :slow do
+    example_line_number = nil
+
+    shared_examples_for "profiles examples" do
+      it "names the example" do
+        expect(output.string).to match(/group example/m)
+      end
+
+      it "prints the time" do
+        expect(output.string).to match(/0(\.\d+)? seconds/)
+      end
+
+      it "prints the path" do
+        filename = __FILE__.split(File::SEPARATOR).last
+        expect(output.string).to match(/#{filename}\:#{example_line_number}/)
+      end
+
+      it "prints the percentage taken from the total runtime" do
+        expect(output.string).to match(/, 100.0% of total time\):/)
+      end
+
+      it "doesn't profile a single example group" do
+        expect(output.string).not_to match(/slowest example groups/)
+      end
+    end
+
+    context "with one example group" do
+      before do
+        example_clock = class_double(RSpec::Core::Time, :now => RSpec::Core::Time.now + 0.5)
+
+        profile(RSpec.describe("group") do
+          example("example") do |example|
+            # make it look slow without actually taking up precious time
+            example.clock = example_clock
+          end
+          example_line_number = __LINE__ - 4
+        end)
+      end
+
+      it_should_behave_like "profiles examples"
+    end
+
+    context "with multiple example groups" do
+      before do
+        example_clock = class_double(RSpec::Core::Time, :now => RSpec::Core::Time.now + 0.5)
+
+        group1 = RSpec.describe("slow group") do
+          example("example") do |example|
+            # make it look slow without actually taking up precious time
+            example.clock = example_clock
+          end
+            example_line_number = __LINE__ - 4
+        end
+        group2 = RSpec.describe("fast group") do
+          example("example 1") { }
+          example("example 2") { }
+        end
+        profile group1, group2
+      end
+
+      it "prints the slowest example groups" do
+        expect(output.string).to match(/slowest example groups/)
+      end
+
+      it "prints the time" do
+        expect(output.string).to match(/0(\.\d+)? seconds/)
+      end
+
+      it "ranks the example groups by average time" do
+        expect(output.string).to match(/slow group(.*)fast group/m)
+      end
+    end
+
+    it "depends on parent_groups to get the top level example group" do
+      ex = nil
+      group = RSpec.describe
+      group.describe("group 2") do
+        describe "group 3" do
+          ex = example("nested example 1")
+        end
+      end
+
+      expect(ex.example_group.parent_groups.last).to eq(group)
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/progress_formatter_spec.rb b/rspec-core/spec/rspec/core/formatters/progress_formatter_spec.rb
new file mode 100644
index 0000000..a92a9fd
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/progress_formatter_spec.rb
@@ -0,0 +1,54 @@
+require 'rspec/core/formatters/progress_formatter'
+
+RSpec.describe RSpec::Core::Formatters::ProgressFormatter do
+  include FormatterSupport
+
+  before do
+    send_notification :start, start_notification(2)
+    allow(formatter).to receive(:color_enabled?).and_return(false)
+  end
+
+  it 'prints a . on example_passed' do
+    send_notification :example_passed, example_notification
+    expect(output.string).to eq(".")
+  end
+
+  it 'prints a * on example_pending' do
+    send_notification :example_pending, example_notification
+    expect(output.string).to eq("*")
+  end
+
+  it 'prints a F on example_failed' do
+    send_notification :example_failed, example_notification
+    expect(output.string).to eq("F")
+  end
+
+  it "produces standard summary without pending when pending has a 0 count" do
+    send_notification :dump_summary, summary_notification(0.00001, examples(2), [], [], 0)
+    expect(output.string).to match(/^\n/)
+    expect(output.string).to match(/2 examples, 0 failures/i)
+    expect(output.string).not_to match(/0 pending/i)
+  end
+
+  it "pushes nothing on start" do
+    #start already sent
+    expect(output.string).to eq("")
+  end
+
+  it "pushes nothing on start dump" do
+    send_notification :start_dump, null_notification
+    expect(output.string).to eq("\n")
+  end
+
+  # The backrace is slightly different on JRuby so we skip there.
+  it 'produces the expected full output', :unless => RUBY_PLATFORM == 'java' do
+    output = run_example_specs_with_formatter("progress")
+    output.gsub!(/ +$/, '') # strip trailing whitespace
+
+    expect(output).to eq(<<-EOS.gsub(/^\s+\|/, ''))
+      |**F.FFF
+      |
+      |#{expected_summary_output_for_example_specs}
+    EOS
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters/snippet_extractor_spec.rb b/rspec-core/spec/rspec/core/formatters/snippet_extractor_spec.rb
new file mode 100644
index 0000000..5227e25
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters/snippet_extractor_spec.rb
@@ -0,0 +1,25 @@
+require 'rspec/core/formatters/snippet_extractor'
+
+module RSpec
+  module Core
+    module Formatters
+      RSpec.describe SnippetExtractor do
+        it "falls back on a default message when it doesn't understand a line" do
+          expect(RSpec::Core::Formatters::SnippetExtractor.new.snippet_for("blech")).to eq(["# Couldn't get snippet for blech", 1])
+        end
+
+        it "falls back on a default message when it doesn't find the file" do
+         expect(RSpec::Core::Formatters::SnippetExtractor.new.lines_around("blech", 8)).to eq("# Couldn't get snippet for blech")
+        end
+
+        it "falls back on a default message when it gets a security error" do
+          message = nil
+          safely do
+            message = RSpec::Core::Formatters::SnippetExtractor.new.lines_around("blech", 8)
+          end
+          expect(message).to eq("# Couldn't get snippet for blech")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/formatters_spec.rb b/rspec-core/spec/rspec/core/formatters_spec.rb
new file mode 100644
index 0000000..1cf61fe
--- /dev/null
+++ b/rspec-core/spec/rspec/core/formatters_spec.rb
@@ -0,0 +1,159 @@
+require 'pathname'
+
+module RSpec::Core::Formatters
+  RSpec.describe Loader do
+
+    let(:output)   { StringIO.new }
+    let(:reporter) { instance_double "Reporter", :register_listener => nil }
+    let(:loader)   { Loader.new reporter }
+
+    describe "#add(formatter)" do
+      let(:path) { File.join(Dir.tmpdir, 'output.txt') }
+
+      it "adds to the list of formatters" do
+        loader.add :documentation, output
+        expect(loader.formatters.first).to be_an_instance_of(DocumentationFormatter)
+      end
+
+      it "finds a formatter by name (w/ Symbol)" do
+        loader.add :documentation, output
+        expect(loader.formatters.first).to be_an_instance_of(DocumentationFormatter)
+      end
+
+      it "finds a formatter by name (w/ String)" do
+        loader.add 'documentation', output
+        expect(loader.formatters.first).to be_an_instance_of(DocumentationFormatter)
+      end
+
+      it "finds a formatter by class" do
+        formatter_class = Class.new(BaseTextFormatter)
+        Loader.formatters[formatter_class] = []
+        loader.add formatter_class, output
+        expect(loader.formatters.first).to be_an_instance_of(formatter_class)
+      end
+
+      it "finds a formatter by class name" do
+        stub_const("CustomFormatter", Class.new(BaseFormatter))
+        Loader.formatters[CustomFormatter] = []
+        loader.add "CustomFormatter", output
+        expect(loader.formatters.first).to be_an_instance_of(CustomFormatter)
+      end
+
+      context "when a legacy formatter is added with RSpec::LegacyFormatters" do
+        formatter_class = Struct.new(:output)
+        let(:formatter) { double "formatter", :notifications => notifications }
+        let(:notifications) { [:a, :b, :c] }
+
+        before do
+          class_double("RSpec::LegacyFormatters", :load_formatter => formatter).as_stubbed_const
+        end
+
+        it "loads formatters from the external gem" do
+          loader.add formatter_class, output
+          expect(loader.formatters).to eq [formatter]
+        end
+
+        it "subscribes the formatter to the notifications the adaptor implements" do
+          expect(reporter).to receive(:register_listener).with(formatter, *notifications)
+          loader.add formatter_class, output
+        end
+      end
+
+      context "when a legacy formatter is added without RSpec::LegacyFormatters" do
+        formatter_class = Struct.new(:output)
+
+        before do
+          allow_deprecation
+        end
+
+        it "issues a deprecation" do
+          expect_warn_deprecation_with_call_site(__FILE__, __LINE__ + 2,
+            /The #{formatter_class} formatter uses the deprecated formatter interface/)
+          loader.add formatter_class, output
+        end
+      end
+
+      it "finds a formatter by class fully qualified name" do
+        stub_const("RSpec::CustomFormatter", (Class.new(BaseFormatter)))
+        Loader.formatters[RSpec::CustomFormatter] = []
+        loader.add "RSpec::CustomFormatter", output
+        expect(loader.formatters.first).to be_an_instance_of(RSpec::CustomFormatter)
+      end
+
+      it "requires a formatter file based on its fully qualified name" do
+        expect(loader).to receive(:require).with('rspec/custom_formatter') do
+          stub_const("RSpec::CustomFormatter", (Class.new(BaseFormatter)))
+          Loader.formatters[RSpec::CustomFormatter] = []
+        end
+        loader.add "RSpec::CustomFormatter", output
+        expect(loader.formatters.first).to be_an_instance_of(RSpec::CustomFormatter)
+      end
+
+      it "raises NameError if class is unresolvable" do
+        expect(loader).to receive(:require).with('rspec/custom_formatter3')
+        expect { loader.add "RSpec::CustomFormatter3", output }.to raise_error(NameError)
+      end
+
+      it "raises ArgumentError if formatter is unknown" do
+        expect { loader.add :progresss, output }.to raise_error(ArgumentError)
+      end
+
+      context "with a 2nd arg defining the output" do
+        it "creates a file at that path and sets it as the output" do
+          loader.add('doc', path)
+          expect(loader.formatters.first.output).to be_a(File)
+          expect(loader.formatters.first.output.path).to eq(path)
+        end
+
+        it "accepts Pathname objects for file paths" do
+          pathname = Pathname.new(path)
+          loader.add('doc', pathname)
+          expect(loader.formatters.first.output).to be_a(File)
+          expect(loader.formatters.first.output.path).to eq(path)
+        end
+      end
+
+      context "when a duplicate formatter exists" do
+        before { loader.add :documentation, output }
+
+        it "doesn't add the formatter for the same output target" do
+          expect {
+            loader.add :documentation, output
+          }.not_to change { loader.formatters.length }
+        end
+
+        it "adds the formatter for different output targets" do
+          expect {
+            loader.add :documentation, path
+          }.to change { loader.formatters.length }
+        end
+      end
+    end
+
+    describe "#setup_default", "with profiling enabled" do
+      let(:setup_default) { loader.setup_default output, output }
+
+      before do
+        allow(RSpec.configuration).to receive(:profile_examples?) { true }
+      end
+
+      context "without an existing profile formatter" do
+        it "will add the profile formatter" do
+          allow(reporter).to receive(:registered_listeners).with(:dump_profile) { [] }
+          setup_default
+          expect(loader.formatters.last).to be_a ::RSpec::Core::Formatters::ProfileFormatter
+        end
+      end
+
+      context "when a formatter that implement #dump_profile is added" do
+        it "wont add the profile formatter" do
+          allow(reporter).to receive(:registered_listeners).with(:dump_profile) { [:json] }
+          setup_default
+          expect(
+            loader.formatters.map(&:class)
+          ).to_not include ::RSpec::Core::Formatters::ProfileFormatter
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/hooks_filtering_spec.rb b/rspec-core/spec/rspec/core/hooks_filtering_spec.rb
new file mode 100644
index 0000000..2cf8196
--- /dev/null
+++ b/rspec-core/spec/rspec/core/hooks_filtering_spec.rb
@@ -0,0 +1,284 @@
+module RSpec::Core
+  RSpec.describe "config block hook filtering" do
+    describe "unfiltered hooks" do
+      it "is run" do
+        filters = []
+        RSpec.configure do |c|
+          c.before(:all) { filters << "before all in config"}
+          c.around(:each) {|example| filters << "around each in config"; example.run}
+          c.before(:each) { filters << "before each in config"}
+          c.after(:each) { filters << "after each in config"}
+          c.after(:all) { filters << "after all in config"}
+        end
+        group = RSpec.describe
+        group.example("example") {}
+        group.run
+        expect(filters).to eq([
+          "before all in config",
+          "around each in config",
+          "before each in config",
+          "after each in config",
+          "after all in config"
+        ])
+      end
+    end
+
+    describe "hooks with single filters" do
+
+      context "with no scope specified" do
+        it "is run around|before|after :each if the filter matches the example group's filter" do
+          filters = []
+          RSpec.configure do |c|
+            c.around(:match => true) {|example| filters << "around each in config"; example.run}
+            c.before(:match => true) { filters << "before each in config"}
+            c.after(:match => true)  { filters << "after each in config"}
+          end
+          group = RSpec.describe("group", :match => true)
+          group.example("example") {}
+          group.run
+          expect(filters).to eq([
+            "around each in config",
+            "before each in config",
+            "after each in config"
+          ])
+        end
+      end
+
+      it "is run if the filter matches the example group's filter" do
+        filters = []
+        RSpec.configure do |c|
+          c.before(:all,  :match => true) { filters << "before all in config"}
+          c.around(:each, :match => true) {|example| filters << "around each in config"; example.run}
+          c.before(:each, :match => true) { filters << "before each in config"}
+          c.after(:each,  :match => true) { filters << "after each in config"}
+          c.after(:all,   :match => true) { filters << "after all in config"}
+        end
+        group = RSpec.describe("group", :match => true)
+        group.example("example") {}
+        group.run
+        expect(filters).to eq([
+          "before all in config",
+          "around each in config",
+          "before each in config",
+          "after each in config",
+          "after all in config"
+        ])
+      end
+
+      it "runs before|after :all hooks on matching nested example groups" do
+        filters = []
+        RSpec.configure do |c|
+          c.before(:all, :match => true) { filters << :before_all }
+          c.after(:all, :match => true)  { filters << :after_all }
+        end
+
+        example_1_filters = example_2_filters = nil
+
+        group = RSpec.describe "group" do
+          it("example 1") { example_1_filters = filters.dup }
+          describe "subgroup", :match => true do
+            it("example 2") { example_2_filters = filters.dup }
+          end
+        end
+        group.run
+
+        expect(example_1_filters).to be_empty
+        expect(example_2_filters).to eq([:before_all])
+        expect(filters).to eq([:before_all, :after_all])
+      end
+
+      it "runs before|after :all hooks only on the highest level group that matches the filter" do
+        filters = []
+        RSpec.configure do |c|
+          c.before(:all, :match => true) { filters << :before_all }
+          c.after(:all, :match => true)  { filters << :after_all }
+        end
+
+        example_1_filters = example_2_filters = example_3_filters = nil
+
+        group = RSpec.describe "group", :match => true do
+          it("example 1") { example_1_filters = filters.dup }
+          describe "subgroup", :match => true do
+            it("example 2") { example_2_filters = filters.dup }
+            describe "sub-subgroup", :match => true do
+              it("example 3") { example_3_filters = filters.dup }
+            end
+          end
+        end
+        group.run
+
+        expect(example_1_filters).to eq([:before_all])
+        expect(example_2_filters).to eq([:before_all])
+        expect(example_3_filters).to eq([:before_all])
+
+        expect(filters).to eq([:before_all, :after_all])
+      end
+
+      it "does not run if the filter doesn't match the example group's filter" do
+        filters = []
+        RSpec.configure do |c|
+          c.before(:all,  :match => false) { filters << "before all in config"}
+          c.around(:each, :match => false) {|example| filters << "around each in config"; example.run}
+          c.before(:each, :match => false) { filters << "before each in config"}
+          c.after(:each,  :match => false) { filters << "after each in config"}
+          c.after(:all,   :match => false) { filters << "after all in config"}
+        end
+        group = RSpec.describe(:match => true)
+        group.example("example") {}
+        group.run
+        expect(filters).to eq([])
+      end
+
+      context "when the hook filters apply to individual examples instead of example groups" do
+        let(:each_filters) { [] }
+        let(:all_filters) { [] }
+
+        let(:example_group) do
+          md = example_metadata
+          RSpec.describe do
+            it("example", md) { }
+          end
+        end
+
+        def filters
+          each_filters + all_filters
+        end
+
+        before(:each) do
+          af, ef = all_filters, each_filters
+
+          RSpec.configure do |c|
+            c.before(:all,  :foo => :bar) { af << "before all in config"}
+            c.around(:each, :foo => :bar) {|example| ef << "around each in config"; example.run}
+            c.before(:each, :foo => :bar) { ef << "before each in config"}
+            c.after(:each,  :foo => :bar) { ef << "after each in config"}
+            c.after(:all,   :foo => :bar) { af << "after all in config"}
+          end
+
+          example_group.run
+        end
+
+        describe 'an example with matching metadata' do
+          let(:example_metadata) { { :foo => :bar } }
+
+          it "runs the `:each` hooks" do
+            expect(each_filters).to eq([
+              'around each in config',
+              'before each in config',
+              'after each in config'
+            ])
+          end
+        end
+
+        describe 'an example without matching metadata' do
+          let(:example_metadata) { { :foo => :bazz } }
+
+          it "does not run any of the hooks" do
+            expect(self.filters).to be_empty
+          end
+        end
+      end
+    end
+
+    describe "hooks with multiple filters" do
+      it "is run if all hook filters match the group's filters" do
+        filters = []
+        RSpec.configure do |c|
+          c.before(:all,  :one => 1)                         { filters << "before all in config"}
+          c.around(:each, :two => 2, :one => 1)              {|example| filters << "around each in config"; example.run}
+          c.before(:each, :one => 1, :two => 2)              { filters << "before each in config"}
+          c.after(:each,  :one => 1, :two => 2, :three => 3) { filters << "after each in config"}
+          c.after(:all,   :one => 1, :three => 3)            { filters << "after all in config"}
+        end
+        group = RSpec.describe("group", :one => 1, :two => 2, :three => 3)
+        group.example("example") {}
+        group.run
+        expect(filters).to eq([
+          "before all in config",
+          "around each in config",
+          "before each in config",
+          "after each in config",
+          "after all in config"
+        ])
+      end
+
+      it "does not run if some hook filters don't match the group's filters" do
+        sequence = []
+
+        RSpec.configure do |c|
+          c.before(:all,  :one => 1, :four => 4)                         { sequence << "before all in config"}
+          c.around(:each, :two => 2, :four => 4)                         {|example| sequence << "around each in config"; example.run}
+          c.before(:each, :one => 1, :two => 2, :four => 4)              { sequence << "before each in config"}
+          c.after(:each,  :one => 1, :two => 2, :three => 3, :four => 4) { sequence << "after each in config"}
+          c.after(:all,   :one => 1, :three => 3, :four => 4)            { sequence << "after all in config"}
+        end
+
+        RSpec.describe "group", :one => 1, :two => 2, :three => 3 do
+          example("ex1") { sequence << "ex1" }
+          example("ex2", :four => 4) { sequence << "ex2" }
+        end.run
+
+        expect(sequence).to eq([
+          "ex1",
+          "before all in config",
+          "around each in config",
+          "before each in config",
+          "ex2",
+          "after each in config",
+          "after all in config"
+        ])
+      end
+
+      it "does not run for examples that do not match, even if their group matches" do
+        filters = []
+
+        RSpec.configure do |c|
+          c.before(:each, :apply_it) { filters << :before_each }
+        end
+
+        RSpec.describe "Group", :apply_it do
+          example("ex1") { filters << :matching_example }
+          example("ex2", :apply_it => false) { filters << :nonmatching_example }
+        end.run
+
+        expect(filters).to eq([:before_each, :matching_example, :nonmatching_example])
+      end
+    end
+
+    describe ":context hooks defined in configuration with metadata" do
+      it 'applies to individual matching examples' do
+        sequence = []
+
+        RSpec.configure do |config|
+          config.before(:context, :apply_it) { sequence << :before_context }
+          config.after(:context, :apply_it)  { sequence << :after_context  }
+        end
+
+        RSpec.describe do
+          example("ex", :apply_it) { sequence << :example }
+        end.run
+
+        expect(sequence).to eq([:before_context, :example, :after_context])
+      end
+
+      it 'does not apply to individual matching examples for which it also applies to a parent example group' do
+        sequence = []
+
+        RSpec.configure do |config|
+          config.before(:context, :apply_it) { sequence << :before_context }
+          config.after(:context, :apply_it)  { sequence << :after_context  }
+        end
+
+        RSpec.describe "Group", :apply_it do
+          example("ex") { sequence << :outer_example }
+
+          context "nested", :apply_it => false do
+            example("ex", :apply_it) { sequence << :inner_example }
+          end
+        end.run
+
+        expect(sequence).to eq([:before_context, :outer_example, :inner_example, :after_context])
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/hooks_spec.rb b/rspec-core/spec/rspec/core/hooks_spec.rb
new file mode 100644
index 0000000..d77b6f4
--- /dev/null
+++ b/rspec-core/spec/rspec/core/hooks_spec.rb
@@ -0,0 +1,429 @@
+module RSpec::Core
+  RSpec.describe Hooks do
+    class HooksHost
+      include Hooks
+
+      def parent_groups
+        []
+      end
+
+      def register_hook(position, scope, *args, &block)
+        block ||= Proc.new { }
+        __send__(position, scope, *args, &block)
+        hook_collection_for(position, scope).first
+      end
+
+      def hook_collection_for(position, scope)
+        hooks.send(:all_hooks_for, position, scope)
+      end
+    end
+
+    [:before, :after, :around].each do |type|
+      [:example, :context].each do |scope|
+        next if type == :around && scope == :context
+
+        describe "##{type}(#{scope})" do
+          it_behaves_like "metadata hash builder" do
+            define_method :metadata_hash do |*args|
+              HooksHost.new.register_hook(type, scope, *args).options
+            end
+          end
+        end
+      end
+
+      describe "##{type}(no scope)" do
+        let(:instance) { HooksHost.new }
+
+        it "defaults to :example scope if no arguments are given" do
+          expect {
+            instance.__send__(type) {}
+          }.to change { instance.hook_collection_for(type, :example).count }.by(1)
+        end
+
+        it "defaults to :example scope if the only argument is a metadata hash" do
+          expect {
+            instance.__send__(type, :foo => :bar) {}
+          }.to change { instance.hook_collection_for(type, :example).count }.by(1)
+        end
+
+        it "raises an error if only metadata symbols are given as arguments" do
+          expect { instance.__send__(type, :foo, :bar) {} }.to raise_error(ArgumentError)
+        end
+      end
+    end
+
+    [:before, :after].each do |type|
+      [:example, :context].each do |scope|
+        describe "##{type}(#{scope.inspect})" do
+          let(:instance) { HooksHost.new }
+          let!(:hook)    { instance.register_hook(type, scope) }
+
+          it "does not make #{scope.inspect} a metadata key" do
+            expect(hook.options).to be_empty
+          end
+
+          it "is scoped to #{scope.inspect}" do
+            expect(instance.hook_collection_for(type, scope)).to include(hook)
+          end
+
+          it 'does not run when in dry run mode' do
+            RSpec.configuration.dry_run = true
+
+            expect { |b|
+              instance.send(type, scope, &b)
+              instance.hooks.run(type, scope, double("Example").as_null_object)
+            }.not_to yield_control
+          end
+        end
+      end
+    end
+
+    describe "#around" do
+      context "when it does not run the example" do
+        context "for a hook declared in the group" do
+          it 'converts the example to a skipped example so the user is made aware of it' do
+            ex = nil
+            group = RSpec.describe do
+              around { }
+              ex = example("not run") { }
+            end
+
+            group.run
+            expect(ex.execution_result.status).to eq(:pending)
+          end
+        end
+
+        context "for a hook declared in config" do
+          it 'converts the example to a skipped example so the user is made aware of it' do
+            RSpec.configuration.around { }
+
+            ex = nil
+            group = RSpec.describe do
+              ex = example("not run") { }
+            end
+
+            group.run
+            expect(ex.execution_result.status).to eq(:pending)
+          end
+        end
+
+        if RUBY_VERSION.to_f < 1.9
+          def hook_desc(_)
+            "around hook"
+          end
+        else
+          def hook_desc(line)
+            "around hook at #{Metadata.relative_path(__FILE__)}:#{line}"
+          end
+        end
+
+        it 'indicates which around hook did not run the example in the pending message' do
+          ex = nil
+          line = __LINE__ + 3
+          group = RSpec.describe do
+            around { |e| e.run }
+            around { }
+            around { |e| e.run }
+
+            ex = example("not run") { }
+          end
+
+          group.run
+          expect(ex.execution_result.pending_message).to eq("#{hook_desc(line)} did not execute the example")
+        end
+      end
+
+      it 'considers the hook to have run when passed as a block to a method that yields' do
+        ex = nil
+        group = RSpec.describe do
+          def transactionally
+            yield
+          end
+
+          around { |e| transactionally(&e) }
+          ex = example("run") { }
+        end
+
+        group.run
+        expect(ex.execution_result.status).to eq(:passed)
+      end
+
+      it 'does not consider the hook to have run when passed as a block to a method that does not yield' do
+        ex = nil
+        group = RSpec.describe do
+          def transactionally; end
+
+          around { |e| transactionally(&e) }
+          ex = example("not run") { }
+        end
+
+        group.run
+        expect(ex.execution_result.status).to eq(:pending)
+      end
+
+      context "when not running the example within the around block" do
+        it "does not run the example" do
+          examples = []
+          group = RSpec.describe do
+            around do
+            end
+            it "foo" do
+              examples << self
+            end
+          end
+          group.run
+          expect(examples).to eq([])
+        end
+      end
+
+      context "when running the example within the around block" do
+        it "runs the example" do
+          examples = []
+          group = RSpec.describe do
+            around do |example|
+              example.run
+            end
+            it "foo" do
+              examples << self
+            end
+          end
+          group.run
+          expect(examples.count).to eq(1)
+        end
+
+        it "exposes example metadata to each around hook" do
+          foos = {}
+          group = RSpec.describe do
+            around do |ex|
+              foos[:first] = ex.metadata[:foo]
+              ex.run
+            end
+            around do |ex|
+              foos[:second] = ex.metadata[:foo]
+              ex.run
+            end
+            it "does something", :foo => :bar do
+            end
+          end
+
+          group.run
+          expect(foos).to eq({:first => :bar, :second => :bar})
+        end
+
+        it "exposes the full example interface to each around hook" do
+          data_1 = {}
+          data_2 = {}
+          ex     = nil
+
+          group = RSpec.describe do
+            def self.data_from(ex)
+              {
+                :description => ex.description,
+                :full_description => ex.full_description,
+                :example_group => ex.example_group,
+                :file_path => ex.file_path,
+                :location => ex.location
+              }
+            end
+
+            around do |example|
+              data_1.update(self.class.data_from example)
+              example.run
+            end
+
+            around do |example|
+              data_2.update(self.class.data_from example)
+              example.run
+            end
+
+            ex = example("the example") { }
+          end
+
+          group.run
+
+          expected_data = group.data_from(ex)
+          expect(data_1).to eq(expected_data)
+          expect(data_2).to eq(expected_data)
+        end
+
+        it "exposes a sensible inspect value" do
+          inspect_value = nil
+          group = RSpec.describe do
+            around do |ex|
+              inspect_value = ex.inspect
+            end
+
+            it "does something" do
+            end
+          end
+
+          group.run
+          expect(inspect_value).to match(/ExampleProcsy/)
+        end
+      end
+
+      context "when running the example within a block passed to a method" do
+        it "runs the example" do
+          examples = []
+          group = RSpec.describe do
+            def yielder
+              yield
+            end
+
+            around do |example|
+              yielder { example.run }
+            end
+
+            it "foo" do
+              examples << self
+            end
+          end
+          group.run
+          expect(examples.count).to eq(1)
+        end
+      end
+    end
+
+    [:all, :each].each do |scope|
+      describe "prepend_before(#{scope})" do
+        it "adds to the front of the list of before(:#{scope}) hooks" do
+          messages = []
+
+          RSpec.configure { |config| config.before(scope)         { messages << "config 3" } }
+          RSpec.configure { |config| config.prepend_before(scope) { messages << "config 2" } }
+          RSpec.configure { |config| config.before(scope)         { messages << "config 4" } }
+          RSpec.configure { |config| config.prepend_before(scope) { messages << "config 1" } }
+
+          group = RSpec.describe { example {} }
+          group.before(scope)         { messages << "group 3" }
+          group.prepend_before(scope) { messages << "group 2" }
+          group.before(scope)         { messages << "group 4" }
+          group.prepend_before(scope) { messages << "group 1" }
+
+          group.run
+
+          expect(messages).to eq([
+            'group 1',
+            'group 2',
+            'config 1',
+            'config 2',
+            'config 3',
+            'config 4',
+            'group 3',
+            'group 4'
+          ])
+        end
+      end
+
+      describe "append_before(#{scope})" do
+        it "adds to the back of the list of before(:#{scope}) hooks (same as `before`)" do
+          messages = []
+
+          RSpec.configure { |config| config.before(scope)        { messages << "config 1" } }
+          RSpec.configure { |config| config.append_before(scope) { messages << "config 2" } }
+          RSpec.configure { |config| config.before(scope)        { messages << "config 3" } }
+
+          group = RSpec.describe { example {} }
+          group.before(scope)        { messages << "group 1" }
+          group.append_before(scope) { messages << "group 2" }
+          group.before(scope)        { messages << "group 3" }
+
+          group.run
+
+          expect(messages).to eq([
+            'config 1',
+            'config 2',
+            'config 3',
+            'group 1',
+            'group 2',
+            'group 3'
+          ])
+        end
+      end
+
+      describe "prepend_after(#{scope})" do
+        it "adds to the front of the list of after(:#{scope}) hooks (same as `after`)" do
+          messages = []
+
+          RSpec.configure { |config| config.after(scope)         { messages << "config 3" } }
+          RSpec.configure { |config| config.prepend_after(scope) { messages << "config 2" } }
+          RSpec.configure { |config| config.after(scope)         { messages << "config 1" } }
+
+          group = RSpec.describe { example {} }
+          group.after(scope)         { messages << "group 3" }
+          group.prepend_after(scope) { messages << "group 2" }
+          group.after(scope)         { messages << "group 1" }
+
+          group.run
+
+          expect(messages).to eq([
+            'group 1',
+            'group 2',
+            'group 3',
+            'config 1',
+            'config 2',
+            'config 3'
+          ])
+        end
+      end
+
+      describe "append_after(#{scope})" do
+        it "adds to the back of the list of after(:#{scope}) hooks" do
+          messages = []
+
+          RSpec.configure { |config| config.after(scope)        { messages << "config 2" } }
+          RSpec.configure { |config| config.append_after(scope) { messages << "config 3" } }
+          RSpec.configure { |config| config.after(scope)        { messages << "config 1" } }
+          RSpec.configure { |config| config.append_after(scope) { messages << "config 4" } }
+
+          group = RSpec.describe { example {} }
+          group.after(scope)        { messages << "group 2" }
+          group.append_after(scope) { messages << "group 3" }
+          group.after(scope)        { messages << "group 1" }
+          group.append_after(scope) { messages << "group 4" }
+
+          group.run
+
+          expect(messages).to eq([
+            'group 1',
+            'group 2',
+            'config 1',
+            'config 2',
+            'config 3',
+            'config 4',
+            'group 3',
+            'group 4'
+          ])
+        end
+      end
+    end
+
+    describe "lambda" do
+      it "can be used as a hook" do
+        messages = []
+        count = 0
+        hook = lambda {|e| messages << "hook #{count = count + 1}"; e.run }
+
+        RSpec.configure do |c|
+          c.around(:each, &hook)
+          c.around(:each, &hook)
+        end
+
+        group = RSpec.describe { example { messages << "example" } }
+        group.run
+        expect(messages).to eq ["hook 1", "hook 2", "example"]
+      end
+    end
+
+    it "only defines methods that are intended to be part of RSpec's public API (+ `hooks`)" do
+      expect(Hooks.private_instance_methods).to eq([])
+
+      expect(Hooks.instance_methods.map(&:to_sym)).to match_array([
+        :before, :after, :around,
+        :append_before, :append_after,
+        :prepend_before, :prepend_after,
+        :hooks
+      ])
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/memoized_helpers_spec.rb b/rspec-core/spec/rspec/core/memoized_helpers_spec.rb
new file mode 100644
index 0000000..7c9ad11
--- /dev/null
+++ b/rspec-core/spec/rspec/core/memoized_helpers_spec.rb
@@ -0,0 +1,535 @@
+module RSpec::Core
+  RSpec.describe MemoizedHelpers do
+    before(:each) { RSpec.configuration.configure_expectation_framework }
+
+    def subject_value_for(describe_arg, &block)
+      example_group = RSpec.describe(describe_arg, &block)
+      subject_value = nil
+      example_group.example { subject_value = subject }
+      example_group.run
+      subject_value
+    end
+
+    describe "implicit subject" do
+      describe "with a class" do
+        it "returns an instance of the class" do
+          expect(subject_value_for(Array)).to eq([])
+        end
+      end
+
+      describe "with a Module" do
+        it "returns the Module" do
+          expect(subject_value_for(Enumerable)).to eq(Enumerable)
+        end
+      end
+
+      describe "with a string" do
+        it "returns the string" do
+          expect(subject_value_for("Foo")).to eq("Foo")
+        end
+      end
+
+      describe "with a number" do
+        it "returns the number" do
+          expect(subject_value_for(15)).to eq(15)
+        end
+      end
+
+      describe "with a hash" do
+        it "returns the hash" do
+          expect(subject_value_for(:foo => 3)).to eq(:foo => 3)
+        end
+      end
+
+      describe "with a symbol" do
+        it "returns the symbol" do
+          expect(subject_value_for(:foo)).to eq(:foo)
+        end
+      end
+
+      describe "with true" do
+        it "returns `true`" do
+          expect(subject_value_for(true)).to eq(true)
+        end
+      end
+
+      describe "with false" do
+        it "returns `false`" do
+          expect(subject_value_for(false)).to eq(false)
+        end
+      end
+
+      describe "with nil" do
+        it "returns `nil`" do
+          expect(subject_value_for(nil)).to eq(nil)
+        end
+      end
+
+      it "can be overriden and super'd to from a nested group" do
+        outer_subject_value = inner_subject_value = nil
+
+        RSpec.describe(Array) do
+          subject { super() << :parent_group }
+          example { outer_subject_value = subject }
+
+          context "nested" do
+            subject { super() << :child_group }
+            example { inner_subject_value = subject }
+          end
+        end.run
+
+        expect(outer_subject_value).to eq([:parent_group])
+        expect(inner_subject_value).to eq([:parent_group, :child_group])
+      end
+    end
+
+    describe "explicit subject" do
+      it "yields the example in which it is eval'd" do
+        example_yielded_to_subject = nil
+        example_yielded_to_example = nil
+
+        example_group = RSpec.describe
+        example_group.subject { |e| example_yielded_to_subject = e }
+        example_group.example { |e| subject; example_yielded_to_example = e }
+        example_group.run
+
+        expect(example_yielded_to_subject).to eq example_yielded_to_example
+      end
+
+      context "doesn't issue a deprecation when used with doubles" do
+        subject do
+          Struct.new(:value) do
+            def working_with?(double)
+              double.value >= value
+            end
+          end.new 1
+        end
+
+        it { should be_working_with double(:value => 10) }
+      end
+
+      [false, nil].each do |falsy_value|
+        context "with a value of #{falsy_value.inspect}" do
+          it "is evaluated once per example" do
+            example_group = RSpec.describe(Array)
+            example_group.before do
+              expect(Object).to receive(:this_question?).once.and_return(falsy_value)
+            end
+            example_group.subject do
+              Object.this_question?
+            end
+            example_group.example do
+              subject
+              subject
+            end
+            expect(example_group.run).to be_truthy, "expected subject block to be evaluated only once"
+          end
+        end
+      end
+
+      describe "defined in a top level group" do
+        it "replaces the implicit subject in that group" do
+          subject_value = subject_value_for(Array) do
+            subject { [1, 2, 3] }
+          end
+          expect(subject_value).to eq([1, 2, 3])
+        end
+      end
+
+      describe "defined in a top level group" do
+        let(:group) do
+          RSpec.describe do
+            subject{ [4, 5, 6] }
+          end
+        end
+
+        it "is available in a nested group (subclass)" do
+          subject_value = nil
+          group.describe("I'm nested!") do
+            example { subject_value = subject }
+          end.run
+
+          expect(subject_value).to eq([4, 5, 6])
+        end
+
+        it "is available in a doubly nested group (subclass)" do
+          subject_value = nil
+          group.describe("Nesting level 1") do
+            describe("Nesting level 2") do
+              example { subject_value = subject }
+            end
+          end.run
+
+          expect(subject_value).to eq([4, 5, 6])
+        end
+
+        it "can be overriden and super'd to from a nested group" do
+          subject_value = nil
+          group.describe("Nested") do
+            subject { super() + [:override] }
+            example { subject_value = subject }
+          end.run
+
+          expect(subject_value).to eq([4, 5, 6, :override])
+        end
+
+        [:before, :after].each do |hook|
+          it "raises an error when referenced from `#{hook}(:all)`" do
+            result = nil
+            line   = nil
+
+            RSpec.describe do
+              subject { nil }
+              send(hook, :all) { result = (subject rescue $!) }; line = __LINE__
+              example { }
+            end.run
+
+            expect(result).to be_an(Exception)
+            expect(result.message).to match(/subject accessed.*#{hook}\(:context\).*#{__FILE__}:#{line}/m)
+          end
+        end
+      end
+
+      describe "with a name" do
+        it "yields the example in which it is eval'd" do
+          example_yielded_to_subject = nil
+          example_yielded_to_example = nil
+
+          group = RSpec.describe
+          group.subject(:foo) { |e| example_yielded_to_subject = e }
+          group.example       { |e| foo; example_yielded_to_example = e }
+          group.run
+
+          expect(example_yielded_to_subject).to eq example_yielded_to_example
+        end
+
+        it "defines a method that returns the memoized subject" do
+          list_value_1 = list_value_2 = subject_value_1 = subject_value_2 = nil
+
+          RSpec.describe do
+            subject(:list) { [1, 2, 3] }
+            example do
+              list_value_1 = list
+              list_value_2 = list
+              subject_value_1 = subject
+              subject_value_2 = subject
+            end
+          end.run
+
+          expect(list_value_1).to eq([1, 2, 3])
+          expect(list_value_1).to equal(list_value_2)
+
+          expect(subject_value_1).to equal(subject_value_2)
+          expect(subject_value_1).to equal(list_value_1)
+        end
+
+        it "is referred from inside subject by the name" do
+          inner_subject_value = nil
+
+          RSpec.describe do
+            subject(:list) { [1, 2, 3] }
+            describe 'first' do
+              subject(:first_element) { list.first }
+              example { inner_subject_value = subject }
+            end
+          end.run
+
+          expect(inner_subject_value).to eq(1)
+        end
+
+        it 'can continue to be referenced by the name even when an inner group redefines the subject' do
+          named_value = nil
+
+          RSpec.describe do
+            subject(:named) { :outer }
+
+            describe "inner" do
+              subject { :inner }
+              example do
+                subject # so the inner subject method is run and memoized
+                named_value = self.named
+              end
+            end
+          end.run
+
+          expect(named_value).to eq(:outer)
+        end
+
+        it 'can continue to reference an inner subject after the outer subject name is referenced' do
+          subject_value = nil
+
+          RSpec.describe do
+            subject(:named) { :outer }
+
+            describe "inner" do
+              subject { :inner }
+              example do
+                named # so the outer subject method is run and memoized
+                subject_value = self.subject
+              end
+            end
+          end.run
+
+          expect(subject_value).to eq(:inner)
+        end
+
+        it 'is not overriden when an inner group defines a new method with the same name' do
+          subject_value = nil
+
+          RSpec.describe do
+            subject(:named) { :outer_subject }
+
+            describe "inner" do
+              let(:named) { :inner_named }
+              example { subject_value = self.subject }
+            end
+          end.run
+
+          expect(subject_value).to be(:outer_subject)
+        end
+
+        context 'when `super` is used' do
+          def should_raise_not_supported_error(&block)
+            ex = nil
+
+            RSpec.describe do
+              let(:list) { ["a", "b", "c"] }
+              subject { [1, 2, 3] }
+
+              describe 'first' do
+                module_exec(&block) if block
+
+                subject(:list) { super().first(2) }
+                ex = example { subject }
+              end
+            end.run
+
+            expect(ex.execution_result.status).to eq(:failed)
+            expect(ex.execution_result.exception.message).to match(/super.*not supported/)
+          end
+
+          it 'raises a "not supported" error' do
+            should_raise_not_supported_error
+          end
+
+          context 'with a `let` definition before the named subject' do
+            it 'raises a "not supported" error' do
+              should_raise_not_supported_error do
+                # My first pass implementation worked unless there was a `let`
+                # declared before the named subject -- this let is in place to
+                # ensure that bug doesn't return.
+                let(:foo) { 3 }
+              end
+            end
+          end
+        end
+      end
+    end
+
+    context "using 'self' as an explicit subject" do
+      it "delegates matcher to the ExampleGroup" do
+        group = RSpec.describe("group") do
+          subject { self }
+          def ok?; true; end
+          def not_ok?; false; end
+
+          it { should eq(self) }
+          it { should be_ok }
+          it { should_not be_not_ok }
+        end
+
+        expect(group.run).to be true
+      end
+
+      it 'supports a new expect-based syntax' do
+        group = RSpec.describe([1, 2, 3]) do
+          it { is_expected.to be_an Array }
+          it { is_expected.not_to include 4 }
+        end
+
+        expect(group.run).to be true
+      end
+    end
+
+    describe '#subject!' do
+      let(:prepared_array) { [1,2,3] }
+      subject! { prepared_array.pop }
+
+      it "evaluates subject before example" do
+        expect(prepared_array).to eq([1,2])
+      end
+
+      it "returns memoized value from first invocation" do
+        expect(subject).to eq(3)
+      end
+    end
+  end
+
+  RSpec.describe "#let" do
+    let(:counter) do
+      Class.new do
+        def initialize
+          @count = 0
+        end
+        def count
+          @count += 1
+        end
+      end.new
+    end
+
+    let(:nil_value) do
+      @nil_value_count += 1
+      nil
+    end
+
+    it "generates an instance method" do
+      expect(counter.count).to eq(1)
+    end
+
+    it "caches the value" do
+      expect(counter.count).to eq(1)
+      expect(counter.count).to eq(2)
+    end
+
+    it "caches a nil value" do
+      @nil_value_count = 0
+      nil_value
+      nil_value
+
+      expect(@nil_value_count).to eq(1)
+    end
+
+    let(:yield_the_example) do |example_yielded_to_let|
+      @example_yielded_to_let = example_yielded_to_let
+    end
+
+    it "yields the example" do |example_yielded_to_example|
+      yield_the_example
+      expect(@example_yielded_to_let).to equal example_yielded_to_example
+    end
+
+    let(:regex_with_capture) { %r[RegexWithCapture(\d)] }
+
+    it 'does not pass the block up the ancestor chain' do
+      # Test for Ruby bug http://bugs.ruby-lang.org/issues/8059
+      expect("RegexWithCapture1".match(regex_with_capture)[1]).to eq('1')
+    end
+
+    it 'raises a useful error when called without a block' do
+      expect do
+        RSpec.describe { let(:list) }
+      end.to raise_error(/#let or #subject called without a block/)
+    end
+
+    let(:a_value) { "a string" }
+
+    context 'when overriding let in a nested context' do
+      let(:a_value) { super() + " (modified)" }
+
+      it 'can use `super` to reference the parent context value' do
+        expect(a_value).to eq("a string (modified)")
+      end
+    end
+
+    context 'when the declaration uses `return`' do
+      let(:value) do
+        return :early_exit if @early_exit
+        :late_exit
+      end
+
+      it 'can exit the let declaration early' do
+        @early_exit = true
+        expect(value).to eq(:early_exit)
+      end
+
+      it 'can get past a conditional `return` statement' do
+        @early_exit = false
+        expect(value).to eq(:late_exit)
+      end
+    end
+
+    [:before, :after].each do |hook|
+      it "raises an error when referenced from `#{hook}(:all)`" do
+        result = nil
+        line   = nil
+
+        RSpec.describe do
+          let(:foo) { nil }
+          send(hook, :all) { result = (foo rescue $!) }; line = __LINE__
+          example { }
+        end.run
+
+        expect(result).to be_an(Exception)
+        expect(result.message).to match(/let declaration `foo` accessed.*#{hook}\(:context\).*#{__FILE__}:#{line}/m)
+      end
+    end
+
+    context "when included modules have hooks that define memoized helpers" do
+      it "allows memoized helpers to override methods in previously included modules" do
+        group = RSpec.describe do
+          include Module.new {
+            def self.included(m); m.let(:unrelated) { :unrelated }; end
+          }
+
+          include Module.new {
+            def hello_message; "Hello from module"; end
+          }
+
+          let(:hello_message) { "Hello from let" }
+        end
+
+        expect(group.new.hello_message).to eq("Hello from let")
+      end
+    end
+  end
+
+  RSpec.describe "#let!" do
+    subject { [1,2,3] }
+    let!(:popped) { subject.pop }
+
+    it "evaluates the value non-lazily" do
+      expect(subject).to eq([1,2])
+    end
+
+    it "returns memoized value from first invocation" do
+      expect(popped).to eq(3)
+    end
+  end
+
+  RSpec.describe 'using subject in before and let blocks' do
+    shared_examples_for 'a subject' do
+      let(:subject_id_in_let) { subject.object_id }
+      before { @subject_id_in_before = subject.object_id }
+
+      it 'should be memoized' do
+        expect(subject_id_in_let).to eq(@subject_id_in_before)
+      end
+
+      it { is_expected.to eq(subject) }
+    end
+
+    describe Object do
+      context 'with implicit subject' do
+        it_should_behave_like 'a subject'
+      end
+
+      context 'with explicit subject' do
+        subject { Object.new }
+        it_should_behave_like 'a subject'
+      end
+
+      context 'with a constant subject'do
+        subject { 123 }
+        it_should_behave_like 'a subject'
+      end
+    end
+  end
+
+  RSpec.describe 'Module#define_method' do
+    it 'is still a private method' do
+      a_module = Module.new
+      expect { a_module.define_method(:name) { "implementation" } }.to raise_error NoMethodError
+    end
+  end
+end
+
diff --git a/rspec-core/spec/rspec/core/metadata_filter_spec.rb b/rspec-core/spec/rspec/core/metadata_filter_spec.rb
new file mode 100644
index 0000000..98b77b3
--- /dev/null
+++ b/rspec-core/spec/rspec/core/metadata_filter_spec.rb
@@ -0,0 +1,175 @@
+module RSpec
+  module Core
+    RSpec.describe MetadataFilter do
+      describe ".filter_applies?" do
+        attr_accessor :parent_group_metadata, :group_metadata, :example_metadata
+
+        def create_metadatas
+          container = self
+
+          RSpec.describe "parent group", :caller => ["/foo_spec.rb:#{__LINE__}"] do; container.parent_group_metadata = metadata
+            describe "group", :caller => ["/foo_spec.rb:#{__LINE__}"] do; container.group_metadata = metadata
+              container.example_metadata = it("example", :caller => ["/foo_spec.rb:#{__LINE__}"], :if => true).metadata
+            end
+          end
+        end
+
+        let(:world) { World.new }
+
+        before do
+          allow(RSpec).to receive(:world) { world }
+          create_metadatas
+        end
+
+        def filter_applies?(key, value, metadata)
+          MetadataFilter.filter_applies?(key, value, metadata)
+        end
+
+        context "with locations" do
+          let(:condition_key){ :locations }
+          let(:parent_group_condition) do
+            {File.expand_path(parent_group_metadata[:file_path]) => [parent_group_metadata[:line_number]]}
+          end
+          let(:group_condition) do
+            {File.expand_path(group_metadata[:file_path]) => [group_metadata[:line_number]]}
+          end
+          let(:example_condition) do
+            {File.expand_path(example_metadata[:file_path]) => [example_metadata[:line_number]]}
+          end
+          let(:between_examples_condition) do
+            {File.expand_path(group_metadata[:file_path]) => [group_metadata[:line_number] + 1]}
+          end
+          let(:next_example_condition) do
+            {File.expand_path(example_metadata[:file_path]) => [example_metadata[:line_number] + 2]}
+          end
+
+          let(:preceeding_declaration_lines) {{
+            parent_group_metadata[:line_number] => parent_group_metadata[:line_number],
+            group_metadata[:line_number] => group_metadata[:line_number],
+            example_metadata[:line_number] => example_metadata[:line_number],
+            (example_metadata[:line_number] + 1) => example_metadata[:line_number],
+            (example_metadata[:line_number] + 2) => example_metadata[:line_number] + 2,
+          }}
+
+          before do
+            expect(world).to receive(:preceding_declaration_line).at_least(:once) do |v|
+              preceeding_declaration_lines[v]
+            end
+          end
+
+          it "matches the group when the line_number is the example group line number" do
+            # this call doesn't really make sense since filter_applies? is only called
+            # for example metadata not group metadata
+            expect(filter_applies?(condition_key, group_condition, group_metadata)).to be_truthy
+          end
+
+          it "matches the example when the line_number is the grandparent example group line number" do
+            expect(filter_applies?(condition_key, parent_group_condition, example_metadata)).to be_truthy
+          end
+
+          it "matches the example when the line_number is the parent example group line number" do
+            expect(filter_applies?(condition_key, group_condition, example_metadata)).to be_truthy
+          end
+
+          it "matches the example when the line_number is the example line number" do
+            expect(filter_applies?(condition_key, example_condition, example_metadata)).to be_truthy
+          end
+
+          it "matches when the line number is between this example and the next" do
+            expect(filter_applies?(condition_key, between_examples_condition, example_metadata)).to be_truthy
+          end
+
+          it "does not match when the line number matches the next example" do
+            expect(filter_applies?(condition_key, next_example_condition, example_metadata)).to be_falsey
+          end
+        end
+
+        it "matches a proc with no arguments that evaluates to true" do
+          expect(filter_applies?(:if, lambda { true }, example_metadata)).to be_truthy
+        end
+
+        it "matches a proc that evaluates to true" do
+          expect(filter_applies?(:if, lambda { |v| v }, example_metadata)).to be_truthy
+        end
+
+        it "does not match a proc that evaluates to false" do
+          expect(filter_applies?(:if, lambda { |v| !v }, example_metadata)).to be_falsey
+        end
+
+        it "matches a proc with an arity of 2" do
+          example_metadata[:foo] = nil
+          expect(filter_applies?(:foo, lambda { |v, m| m == example_metadata }, example_metadata)).to be_truthy
+        end
+
+        it "raises an error when the proc has an incorrect arity" do
+          expect {
+            filter_applies?(:if, lambda { |a,b,c| true }, example_metadata)
+          }.to raise_error(ArgumentError)
+        end
+
+        context "with a nested hash" do
+          it 'matches when the nested entry matches' do
+            metadata = { :foo => { :bar => "words" } }
+            expect(filter_applies?(:foo, { :bar => /wor/ }, metadata)).to be_truthy
+          end
+
+          it 'does not match when the nested entry does not match' do
+            metadata = { :foo => { :bar => "words" } }
+            expect(filter_applies?(:foo, { :bar => /sword/ }, metadata)).to be_falsey
+          end
+
+          it 'does not match when the metadata lacks the key' do
+            expect(filter_applies?(:foo, { :bar => /sword/ }, {})).to be_falsey
+          end
+
+          it 'does not match when the metadata does not have a hash entry for the key' do
+            metadata = { :foo => "words" }
+            expect(filter_applies?(:foo, { :bar => /word/ }, metadata)).to be_falsey
+          end
+        end
+
+        context "with an Array" do
+          let(:metadata_with_array) do
+            meta = nil
+            RSpec.describe("group") do
+              meta = example('example_with_array', :tag => [:one, 2, 'three', /four/]).metadata
+            end
+            meta
+          end
+
+          it "matches a symbol" do
+            expect(filter_applies?(:tag, 'one', metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, :one, metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, 'two', metadata_with_array)).to be_falsey
+          end
+
+          it "matches a string" do
+            expect(filter_applies?(:tag, 'three', metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, :three, metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, 'tree', metadata_with_array)).to be_falsey
+          end
+
+          it "matches an integer" do
+            expect(filter_applies?(:tag, '2', metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, 2, metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, 3, metadata_with_array)).to be_falsey
+          end
+
+          it "matches a regexp" do
+            expect(filter_applies?(:tag, 'four', metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, 'fourtune', metadata_with_array)).to be_truthy
+            expect(filter_applies?(:tag, 'fortune', metadata_with_array)).to be_falsey
+          end
+
+          it "matches a proc that evaluates to true" do
+            expect(filter_applies?(:tag, lambda { |values| values.include? 'three' }, metadata_with_array)).to be_truthy
+          end
+
+          it "does not match a proc that evaluates to false" do
+            expect(filter_applies?(:tag, lambda { |values| values.include? 'nothing' }, metadata_with_array)).to be_falsey
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/metadata_spec.rb b/rspec-core/spec/rspec/core/metadata_spec.rb
new file mode 100644
index 0000000..b646a7d
--- /dev/null
+++ b/rspec-core/spec/rspec/core/metadata_spec.rb
@@ -0,0 +1,740 @@
+module RSpec
+  module Core
+    RSpec.describe Metadata do
+
+      describe '.relative_path' do
+        let(:here) { File.expand_path(".") }
+        it "transforms absolute paths to relative paths" do
+          expect(Metadata.relative_path(here)).to eq "."
+        end
+        it "transforms absolute paths to relative paths anywhere in its argument" do
+          expect(Metadata.relative_path("foo #{here} bar")).to eq "foo . bar"
+        end
+        it "returns nil if passed an unparseable file:line combo" do
+          expect(Metadata.relative_path("-e:1")).to be_nil
+        end
+        # I have no idea what line = line.sub(/\A([^:]+:\d+)$/, '\\1') is supposed to do
+        it "gracefully returns nil if run in a secure thread" do
+          safely do
+            value = Metadata.relative_path(".")
+            # on some rubies, File.expand_path is not a security error, so accept "." as well
+            expect([nil, "."]).to include(value)
+          end
+        end
+
+        it 'should not transform directories beginning with the same prefix' do
+          #E.g. /foo/bar_baz is not relative to /foo/bar !!
+
+          similar_directory = "#{File.expand_path(".")}_similar"
+          expect(Metadata.relative_path(similar_directory)).to eq similar_directory
+        end
+
+      end
+
+      context "when created" do
+        Metadata::RESERVED_KEYS.each do |key|
+          it "prohibits :#{key} as a hash key for an example group" do
+            expect {
+              RSpec.describe("group", key => {})
+            }.to raise_error(/:#{key} is not allowed/)
+          end
+
+          it "prohibits :#{key} as a hash key for an example" do
+            group = RSpec.describe("group")
+            expect {
+              group.example("example", key => {})
+            }.to raise_error(/:#{key} is not allowed/)
+          end
+        end
+
+        it "uses :caller if passed as part of the user metadata" do
+          m = nil
+
+          RSpec.describe('group', :caller => ['example_file:42']) do
+            m = metadata
+          end
+
+          expect(m[:location]).to eq("example_file:42")
+        end
+      end
+
+      context "for an example" do
+        let(:line_number) { __LINE__ + 3 }
+        def metadata_for(*args)
+          RSpec.describe("group description") do
+            return example(*args).metadata
+          end
+        end
+        alias example_metadata metadata_for
+
+        RSpec::Matchers.define :have_value do |value|
+          chain(:for) { |key| @key = key }
+
+          match do |meta|
+            expect(meta.fetch(@key)).to eq(value)
+            expect(meta[@key]).to eq(value)
+          end
+        end
+
+        it "stores the description args" do
+          expect(metadata_for "example description").to have_value(["example description"]).for(:description_args)
+        end
+
+        it "ignores nil description args" do
+          expect(example_metadata).to have_value([]).for(:description_args)
+        end
+
+        it "stores the full_description (group description + example description)" do
+          expect(metadata_for "example description").to have_value("group description example description").for(:full_description)
+        end
+
+        it "creates an empty execution result" do
+          expect(example_metadata[:execution_result].to_h.reject { |_, v| v.nil? } ).to eq({})
+        end
+
+        it "extracts file path from caller" do
+          expect(example_metadata).to have_value(relative_path(__FILE__)).for(:file_path)
+        end
+
+        it "extracts line number from caller" do
+          expect(example_metadata).to have_value(line_number).for(:line_number)
+        end
+
+        it "extracts location from caller" do
+          expect(example_metadata).to have_value("#{relative_path(__FILE__)}:#{line_number}").for(:location)
+        end
+
+        it "uses :caller if passed as an option" do
+          example_metadata = metadata_for('example description', :caller => ['example_file:42'])
+          expect(example_metadata).to have_value("example_file:42").for(:location)
+        end
+
+        it "merges arbitrary options" do
+          expect(metadata_for("desc", :arbitrary => :options)).to have_value(:options).for(:arbitrary)
+        end
+
+        it "points :example_group to the same hash object as other examples in the same group" do
+          a = b = nil
+
+          RSpec.describe "group" do
+            a = example("foo").metadata[:example_group]
+            b = example("bar").metadata[:example_group]
+          end
+
+          a[:description] = "new description"
+
+          pending "Cannot maintain this and provide full `:example_group` backwards compatibility (see GH #1490):("
+          expect(b[:description]).to eq("new description")
+        end
+
+        it 'does not include example-group specific keys' do
+          meta = nil
+
+          RSpec.describe "group" do
+            context "nested" do
+              meta = example("foo").metadata
+            end
+          end
+
+          expect(meta.keys).not_to include(:parent_example_group)
+        end
+      end
+
+      describe ":block" do
+        context "for example group metadata" do
+          it "contains the example group block" do
+            block = Proc.new { }
+            group = RSpec.describe("group", &block)
+            expect(group.metadata[:block]).to equal(block)
+          end
+        end
+
+        context "for example metadata" do
+          it "contains the example block" do
+            block = Proc.new { }
+            group = RSpec.describe("group")
+            example = group.example("example", &block)
+            expect(example.metadata[:block]).to equal(block)
+          end
+        end
+      end
+
+      describe ":shared_group_inclusion_backtrace" do
+        context "for an example group" do
+          it "is not set since we do not yet need it internally (but we can add it in the future if needed)" do
+            group = RSpec.describe("group")
+            expect(group.metadata).not_to include(:shared_group_inclusion_backtrace)
+          end
+        end
+
+        context "for an example" do
+          context "not generated by a shared group" do
+            it "is a blank array" do
+              meta = nil
+              RSpec.describe { meta = example { }.metadata }
+              expect(meta).to include(:shared_group_inclusion_backtrace => [])
+            end
+          end
+
+          context "generated by an unnested shared group included via metadata" do
+            it "is an array containing an object with shared group name and inclusion location" do
+              meta = nil
+
+              RSpec.shared_examples_for("some shared behavior", :include_it => true) do
+                meta = example { }.metadata
+              end
+
+              line = __LINE__ + 1
+              RSpec.describe("Group", :include_it => true) { }
+
+              expect(meta[:shared_group_inclusion_backtrace]).to match [ an_object_having_attributes(
+                :shared_group_name  => "some shared behavior",
+                :inclusion_location => a_string_including("#{Metadata.relative_path __FILE__}:#{line}")
+              ) ]
+            end
+          end
+
+          {
+            :it_behaves_like  => "generates a nested group",
+            :include_examples => "adds the examples directly to the host group"
+          }.each do |inclusion_method, description|
+            context "generated by an unnested shared group using an inclusion method that #{description}" do
+              it "is an array containing an object with shared group name and inclusion location" do
+                meta = nil
+
+                RSpec.shared_examples_for("some shared behavior") do
+                  meta = example { }.metadata
+                end
+
+                line = __LINE__ + 2
+                RSpec.describe do
+                  __send__ inclusion_method, "some shared behavior"
+                end
+
+                expect(meta[:shared_group_inclusion_backtrace]).to match [ an_object_having_attributes(
+                  :shared_group_name  => "some shared behavior",
+                  :inclusion_location => a_string_including("#{Metadata.relative_path __FILE__}:#{line}")
+                ) ]
+              end
+            end
+
+            context "generated by a nested shared group using an inclusion method that #{description}" do
+              it "contains a stack frame for each inclusion, in the same order as ruby backtraces" do
+                meta = nil
+
+                RSpec.shared_examples_for "inner" do
+                  meta = example { }.metadata
+                end
+
+                inner_line = __LINE__ + 2
+                RSpec.shared_examples_for "outer" do
+                  __send__ inclusion_method, "inner"
+                end
+
+                outer_line = __LINE__ + 2
+                RSpec.describe do
+                  __send__ inclusion_method, "outer"
+                end
+
+                expect(meta[:shared_group_inclusion_backtrace]).to match [
+                  an_object_having_attributes(
+                    :shared_group_name  => "inner",
+                    :inclusion_location => a_string_including("#{Metadata.relative_path __FILE__}:#{inner_line}")
+                  ),
+                  an_object_having_attributes(
+                    :shared_group_name  => "outer",
+                    :inclusion_location => a_string_including("#{Metadata.relative_path __FILE__}:#{outer_line}")
+                  ),
+                ]
+              end
+            end
+          end
+        end
+      end
+
+      describe ":described_class" do
+        value_from = lambda do |group|
+          group.metadata[:described_class]
+        end
+
+        context "in an outer group" do
+          define_method :value_for do |arg|
+            value_from[RSpec.describe(arg)]
+          end
+
+          context "with a String" do
+            it "returns nil" do
+              expect(value_for "group").to be_nil
+            end
+          end
+
+          context "with a Symbol" do
+            it "returns the symbol" do
+              expect(value_for :group).to be(:group)
+            end
+          end
+
+          context "with a class" do
+            it "returns the class" do
+              expect(value_for String).to be(String)
+            end
+
+            context "when the class is Regexp" do
+              it "returns the class" do
+                expect(value_for Regexp).to be(Regexp)
+              end
+            end
+          end
+        end
+
+        context "in a nested group" do
+          it "inherits the parent group's described class" do
+            value = nil
+
+            RSpec.describe(Hash) do
+              describe "sub context" do
+                value = value_from[self]
+              end
+            end
+
+            expect(value).to be(Hash)
+          end
+
+          it "sets the described class when passing a class" do
+            value = nil
+
+            RSpec.describe(String) do
+              describe Array do
+                value = value_from[self]
+              end
+            end
+
+            expect(value).to be(Array)
+          end
+
+          it 'does not override the :described_class when passing no describe args' do
+            value = nil
+
+            RSpec.describe(String) do
+              describe do
+                value = value_from[self]
+              end
+            end
+
+            expect(value).to be(String)
+          end
+
+          it "can override a parent group's described class using metdata" do
+            parent_value = child_value = grandchild_value = nil
+
+            RSpec.describe(String) do
+              parent_value = value_from[self]
+
+              describe "sub context" do
+                metadata[:described_class] = Hash
+                child_value = value_from[self]
+
+                describe "sub context" do
+                  grandchild_value = value_from[self]
+                end
+              end
+            end
+
+            expect(grandchild_value).to be(Hash)
+            expect(child_value).to be(Hash)
+            expect(parent_value).to be(String)
+          end
+        end
+      end
+
+      describe ":description" do
+        context "on a example" do
+          it "just has the example description" do
+            value = nil
+
+            RSpec.describe "group" do
+              value = example("example").metadata[:description]
+            end
+
+            expect(value).to eq("example")
+          end
+        end
+
+        context "on a group" do
+          def group_value_for(*args)
+            value = nil
+
+            RSpec.describe(*args) do
+              value = metadata[:description]
+            end
+
+            value
+          end
+
+          context "with a string" do
+            it "provides the submitted description" do
+              expect(group_value_for "group").to eq("group")
+            end
+          end
+
+          context "with a non-string" do
+            it "provides the string form of the submitted object" do
+              expect(group_value_for Hash).to eq("Hash")
+            end
+          end
+
+          context "with a non-string and a string" do
+            it "concats the args" do
+              expect(group_value_for Object, 'group').to eq("Object group")
+            end
+          end
+
+          context "with a string and a non-string" do
+            it "concats the args" do
+              expect(group_value_for 'group', Object).to eq("group Object")
+            end
+          end
+
+          context "with empty args" do
+            it "returns empty string for [:description]" do
+              expect(group_value_for()).to eq("")
+            end
+          end
+        end
+      end
+
+      describe ":full_description" do
+        context "on an example" do
+          it "concats example group name and description" do
+            value = nil
+
+            RSpec.describe "group" do
+              value = example("example").metadata[:full_description]
+            end
+
+            expect(value).to eq("group example")
+          end
+        end
+
+        it "concats nested example group descriptions" do
+          group_value = example_value = nil
+
+          RSpec.describe "parent" do
+            describe "child" do
+              group_value = metadata[:full_description]
+              example_value = example("example").metadata[:full_description]
+            end
+          end
+
+          expect(group_value).to eq("parent child")
+          expect(example_value).to eq("parent child example")
+        end
+
+        it "concats nested example group descriptions three deep" do
+          grandparent_value = parent_value = child_value = example_value = nil
+
+          RSpec.describe "grandparent" do
+            grandparent_value = metadata[:full_description]
+            describe "parent" do
+              parent_value = metadata[:full_description]
+              describe "child" do
+                child_value = metadata[:full_description]
+                example_value = example("example").metadata[:full_description]
+              end
+            end
+          end
+
+          expect(grandparent_value).to eq("grandparent")
+          expect(parent_value).to eq("grandparent parent")
+          expect(child_value).to eq("grandparent parent child")
+          expect(example_value).to eq("grandparent parent child example")
+        end
+
+        %w[# . ::].each do |char|
+          context "with a 2nd arg starting with #{char}" do
+            it "removes the space" do
+              value = nil
+
+              RSpec.describe Array, "#{char}method" do
+                value = metadata[:full_description]
+              end
+
+              expect(value).to eq("Array#{char}method")
+            end
+          end
+
+          context "with a description starting with #{char} nested under a module" do
+            it "removes the space" do
+              value = nil
+
+              RSpec.describe Object do
+                describe "#{char}method" do
+                  value = metadata[:full_description]
+                end
+              end
+
+              expect(value).to eq("Object#{char}method")
+            end
+          end
+
+          context "with a description starting with #{char} nested under a context string" do
+            it "does not remove the space" do
+              value = nil
+
+              RSpec.describe(Array) do
+                context "with 2 items" do
+                  describe "#{char}method" do
+                    value = metadata[:full_description]
+                  end
+                end
+              end
+
+              expect(value).to eq("Array with 2 items #{char}method")
+            end
+          end
+        end
+      end
+
+      describe ":file_path" do
+        it "finds the first non-rspec lib file in the caller array" do
+          value = nil
+
+          RSpec.describe(:caller => ["./lib/rspec/core/foo.rb", "#{__FILE__}:#{__LINE__}"]) do
+            value = metadata[:file_path]
+          end
+
+          expect(value).to eq(relative_path(__FILE__))
+        end
+      end
+
+      describe ":line_number" do
+        def value_for(*args)
+          value = nil
+
+          @describe_line = __LINE__ + 1
+          RSpec.describe("group", *args) do
+            value = metadata[:line_number]
+          end
+
+          value
+        end
+
+        it "finds the line number with the first non-rspec lib file in the backtrace" do
+          expect(value_for()).to eq(@describe_line)
+        end
+
+        it "finds the line number with the first spec file with drive letter" do
+          expect(value_for(:caller => [ "C:/path/to/file_spec.rb:#{__LINE__}" ])).to eq(__LINE__)
+        end
+
+        it "uses the number after the first : for ruby 1.9" do
+          expect(value_for(:caller => [ "#{__FILE__}:#{__LINE__}:999" ])).to eq(__LINE__)
+        end
+      end
+
+      describe "child example group" do
+        it "nests the parent's example group metadata" do
+          child = parent = nil
+
+          RSpec.describe Object, "parent" do
+            parent = metadata
+            describe { child = metadata }
+          end
+
+          expect(child[:parent_example_group]).to eq(parent)
+        end
+      end
+
+      it 'does not have a `:parent_example_group` key for a top level group' do
+        meta = RSpec.describe(Object).metadata
+        expect(meta).not_to include(:parent_example_group)
+      end
+
+      describe "backwards compatibility" do
+        before { allow_deprecation }
+
+        describe ":example_group" do
+          it 'issues a deprecation warning when the `:example_group` key is accessed' do
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 2, /:example_group/)
+            RSpec.describe(Object, "group") do
+              metadata[:example_group]
+            end
+          end
+
+          it 'does not issue a deprecation warning when :example_group is accessed while applying configured filterings' do
+            RSpec.configuration.include Module.new, :example_group => { :file_path => /.*/ }
+            expect_no_deprecation
+            RSpec.describe(Object, "group")
+          end
+
+          it 'can still access the example group attributes via [:example_group]' do
+            meta = nil
+            RSpec.describe(Object, "group") { meta = metadata }
+
+            expect(meta[:example_group][:line_number]).to eq(__LINE__ - 2)
+            expect(meta[:example_group][:description]).to eq("Object group")
+          end
+
+          it 'can access the parent example group attributes via [:example_group][:example_group]' do
+            parent = child = nil
+            parent_line = __LINE__ + 1
+            RSpec.describe(Object, "group", :foo => 3) do
+              parent = metadata
+              describe("nested") { child = metadata }
+            end
+
+            expect(child[:example_group][:example_group].to_h).to include(
+              :foo => 3,
+              :description => "Object group",
+              :line_number => parent_line
+            )
+          end
+
+          it "works properly with deep nesting" do
+            inner_metadata = nil
+
+            RSpec.describe "Level 1" do
+              describe "Level 2" do
+                describe "Level 3" do
+                  inner_metadata = example("Level 4").metadata
+                end
+              end
+            end
+
+            expect(inner_metadata[:description]).to eq("Level 4")
+            expect(inner_metadata[:example_group][:description]).to eq("Level 3")
+            expect(inner_metadata[:example_group][:example_group][:description]).to eq("Level 2")
+            expect(inner_metadata[:example_group][:example_group][:example_group][:description]).to eq("Level 1")
+            expect(inner_metadata[:example_group][:example_group][:example_group][:example_group]).to be_nil
+          end
+
+          it "works properly with shallow nesting" do
+            inner_metadata = nil
+
+            RSpec.describe "Level 1" do
+              inner_metadata = example("Level 2").metadata
+            end
+
+            expect(inner_metadata[:description]).to eq("Level 2")
+            expect(inner_metadata[:example_group][:description]).to eq("Level 1")
+            expect(inner_metadata[:example_group][:example_group]).to be_nil
+          end
+
+          it 'allows integration libraries like VCR to infer a fixture name from the example description by walking up nesting structure' do
+            fixture_name_for = lambda do |meta|
+              description = meta[:description]
+
+              if example_group = meta[:example_group]
+                [fixture_name_for[example_group], description].join('/')
+              else
+                description
+              end
+            end
+
+            ex = inferred_fixture_name = nil
+
+            RSpec.configure do |config|
+              config.before(:example, :infer_fixture) { |e| inferred_fixture_name = fixture_name_for[e.metadata] }
+            end
+
+            RSpec.describe "Group", :infer_fixture do
+              ex = example("ex") { }
+            end.run
+
+            raise ex.execution_result.exception if ex.execution_result.exception
+
+            expect(inferred_fixture_name).to eq("Group/ex")
+          end
+
+          it 'can mutate attributes when accessing them via [:example_group]' do
+            meta = nil
+
+            RSpec.describe(String) do
+              describe "sub context" do
+                meta = metadata
+              end
+            end
+
+            expect {
+              meta[:example_group][:described_class] = Hash
+            }.to change { meta[:described_class] }.from(String).to(Hash)
+          end
+
+          it 'can still be filtered via a nested key under [:example_group] as before' do
+            meta = nil
+
+            line = __LINE__ + 1
+            RSpec.describe("group") { meta = metadata }
+
+            applies = MetadataFilter.apply?(
+              :any?,
+              { :example_group => { :line_number => line } },
+              meta
+            )
+
+            expect(applies).to be true
+          end
+        end
+
+        describe ":example_group_block" do
+          it 'returns the block' do
+            meta = nil
+
+            RSpec.describe "group" do
+              meta = metadata
+            end
+
+            expect(meta[:example_group_block]).to be_a(Proc).and eq(meta[:block])
+          end
+
+          it 'issues a deprecation warning' do
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 2, /:example_group_block/)
+            RSpec.describe "group" do
+              metadata[:example_group_block]
+            end
+          end
+        end
+
+        describe ":describes" do
+          context "on an example group metadata hash" do
+            it 'returns the described_class' do
+              meta = nil
+
+              RSpec.describe Hash do
+                meta = metadata
+              end
+
+              expect(meta[:describes]).to be(Hash).and eq(meta[:described_class])
+            end
+
+            it 'issues a deprecation warning' do
+              expect_deprecation_with_call_site(__FILE__, __LINE__ + 2, /:describes/)
+              RSpec.describe "group" do
+                metadata[:describes]
+              end
+            end
+          end
+
+          context "an an example metadata hash" do
+            it 'returns the described_class' do
+              meta = nil
+
+              RSpec.describe Hash do
+                meta = example("ex").metadata
+              end
+
+              expect(meta[:describes]).to be(Hash).and eq(meta[:described_class])
+            end
+
+            it 'issues a deprecation warning' do
+              expect_deprecation_with_call_site(__FILE__, __LINE__ + 2, /:describes/)
+              RSpec.describe "group" do
+                example("ex").metadata[:describes]
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/notifications_spec.rb b/rspec-core/spec/rspec/core/notifications_spec.rb
new file mode 100644
index 0000000..83428f5
--- /dev/null
+++ b/rspec-core/spec/rspec/core/notifications_spec.rb
@@ -0,0 +1,104 @@
+require 'rspec/core/notifications'
+require 'pathname'
+
+RSpec.describe "FailedExampleNotification" do
+  include FormatterSupport
+
+  let(:notification) { ::RSpec::Core::Notifications::FailedExampleNotification.new(example) }
+
+  before do
+    example.metadata[:absolute_file_path] = __FILE__
+  end
+
+  # ported from `base_formatter_spec` should be refactored by final
+  describe "#read_failed_line" do
+    context "when backtrace is a heterogeneous language stack trace" do
+      let(:exception) do
+        instance_double(Exception, :backtrace => [
+          "at Object.prototypeMethod (foo:331:18)",
+          "at Array.forEach (native)",
+          "at a_named_javascript_function (/some/javascript/file.js:39:5)",
+          "/some/line/of/ruby.rb:14"
+        ])
+      end
+
+      it "is handled gracefully" do
+        expect { notification.send(:read_failed_line) }.not_to raise_error
+      end
+    end
+
+    context "when backtrace will generate a security error" do
+      let(:exception) { instance_double(Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"]) }
+
+      it "is handled gracefully" do
+        safely do
+          expect { notification.send(:read_failed_line) }.not_to raise_error
+        end
+      end
+    end
+
+    context "when ruby reports a bogus line number in the stack trace" do
+      let(:exception) { instance_double(Exception, :backtrace => [ "#{__FILE__}:10000000"]) }
+
+      it "reports the filename and that it was unable to find the matching line" do
+        expect(notification.send(:read_failed_line)).to include("Unable to find matching line")
+      end
+    end
+
+    context "when the stacktrace includes relative paths (which can happen when using `rspec/autorun` and running files through `ruby`)" do
+      let(:relative_file) { Pathname(__FILE__).relative_path_from(Pathname(Dir.pwd)) }
+      line = __LINE__
+      let(:exception) { instance_double(Exception, :backtrace => ["#{relative_file}:#{line}"]) }
+
+      it 'still finds the backtrace line' do
+        expect(notification.send(:read_failed_line)).to include("line = __LINE__")
+      end
+    end
+
+    context "when String alias to_int to_i" do
+      before do
+        String.class_exec do
+          alias :to_int :to_i
+        end
+      end
+
+      after do
+        String.class_exec do
+          undef to_int
+        end
+      end
+
+      let(:exception) { instance_double(Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"]) }
+
+      it "doesn't hang when file exists" do
+        expect(notification.send(:read_failed_line).strip).to eql(
+          %Q[let(:exception) { instance_double(Exception, :backtrace => [ "\#{__FILE__}:\#{__LINE__}"]) }])
+      end
+
+    end
+  end
+
+  describe '#message_lines' do
+    let(:exception) { instance_double(Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"], :message => 'Test exception') }
+    let(:example_group) { class_double(RSpec::Core::ExampleGroup, :metadata => {}, :parent_groups => [], :location => "#{__FILE__}:#{__LINE__}") }
+
+    before do
+      allow(example).to receive(:example_group) { example_group }
+    end
+
+    it 'should return failure_lines without color' do
+      lines = notification.message_lines
+      expect(lines[0]).to match %r{\AFailure\/Error}
+      expect(lines[1]).to match %r{\A\s*Test exception\z}
+    end
+
+    it 'returns failures_lines without color when they are part of a shared example group' do
+      example.metadata[:shared_group_inclusion_backtrace] <<
+        RSpec::Core::SharedExampleGroupInclusionStackFrame.new("foo", "bar")
+
+      lines = notification.message_lines
+      expect(lines[0]).to match %r{\AFailure\/Error}
+      expect(lines[1]).to match %r{\A\s*Test exception\z}
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/option_parser_spec.rb b/rspec-core/spec/rspec/core/option_parser_spec.rb
new file mode 100644
index 0000000..f387dbb
--- /dev/null
+++ b/rspec-core/spec/rspec/core/option_parser_spec.rb
@@ -0,0 +1,281 @@
+module RSpec::Core
+  RSpec.describe OptionParser do
+    before do
+      allow(RSpec.configuration).to receive(:reporter) do
+        fail "OptionParser is not allowed to access `config.reporter` since we want " +
+             "ConfigurationOptions to have the chance to set `deprecation_stream` " +
+             "(based on `--deprecation-out`) before the deprecation formatter is " +
+             "initialized by the reporter instantiation. If you need to issue a deprecation, " +
+             "populate an `options[:deprecations]` key and have ConfigurationOptions " +
+             "issue the deprecation after configuring `deprecation_stream`"
+      end
+    end
+
+    it "does not parse empty args" do
+      parser = Parser.new
+      expect(OptionParser).not_to receive(:new)
+      parser.parse([])
+    end
+
+    it "proposes you to use --help and returns an error on incorrect argument" do
+      parser = Parser.new
+      option = "--my_wrong_arg"
+
+      expect(parser).to receive(:abort) do |msg|
+        expect(msg).to include('use --help', option)
+      end
+
+      parser.parse([option])
+    end
+
+    {
+      '--init'         => ['-i','--I'],
+      '--default-path' => ['-d'],
+      '--dry-run'      => ['-d'],
+      '--drb-port'     => ['-d'],
+    }.each do |long, shorts|
+      shorts.each do |option|
+        it "won't parse #{option} as a shorthand for #{long}" do
+          parser = Parser.new
+
+          expect(parser).to receive(:abort) do |msg|
+            expect(msg).to include('use --help', option)
+          end
+
+          parser.parse([option])
+        end
+      end
+    end
+
+    it "won't display invalid options in the help output" do
+      def generate_help_text
+        parser = Parser.new
+        allow(parser).to receive(:exit)
+        parser.parse(["--help"])
+      end
+
+      useless_lines = /^\s*--?\w+\s*$\n/
+
+      expect { generate_help_text }.to_not output(useless_lines).to_stdout
+    end
+
+    describe "-I" do
+      it "sets the path" do
+        options = Parser.parse(%w[-I path/to/foo])
+        expect(options[:libs]).to eq %w[path/to/foo]
+      end
+
+      context "with a string containing `#{File::PATH_SEPARATOR}`" do
+        it "splits into multiple paths, just like Ruby's `-I` option" do
+          options = Parser.parse(%W[-I path/to/foo -I path/to/bar#{File::PATH_SEPARATOR}path/to/baz])
+          expect(options[:libs]).to eq %w[path/to/foo path/to/bar path/to/baz]
+        end
+      end
+    end
+
+    describe "--default-path" do
+      it "sets the default path where RSpec looks for examples" do
+        options = Parser.parse(%w[--default-path foo])
+        expect(options[:default_path]).to eq "foo"
+      end
+    end
+
+    %w[--format -f].each do |option|
+      describe option do
+        it "defines the formatter" do
+          options = Parser.parse([option, 'doc'])
+          expect(options[:formatters].first).to eq(["doc"])
+        end
+      end
+    end
+
+    %w[--out -o].each do |option|
+      describe option do
+        it "sets the output stream for the formatter" do
+          options = Parser.parse([option, 'out.txt'])
+          expect(options[:formatters].last).to eq(['progress', 'out.txt'])
+        end
+
+        context "with multiple formatters" do
+          context "after last formatter" do
+            it "sets the output stream for the last formatter" do
+              options = Parser.parse(['-f', 'progress', '-f', 'doc', option, 'out.txt'])
+              expect(options[:formatters][0]).to eq(['progress'])
+              expect(options[:formatters][1]).to eq(['doc', 'out.txt'])
+            end
+          end
+
+          context "after first formatter" do
+            it "sets the output stream for the first formatter" do
+              options = Parser.parse(['-f', 'progress', option, 'out.txt', '-f', 'doc'])
+              expect(options[:formatters][0]).to eq(['progress', 'out.txt'])
+              expect(options[:formatters][1]).to eq(['doc'])
+            end
+          end
+        end
+      end
+    end
+
+    describe "--deprecation-out" do
+      it 'sets the deprecation stream' do
+        options = Parser.parse(["--deprecation-out", "path/to/log"])
+        expect(options).to include(:deprecation_stream => "path/to/log")
+      end
+    end
+
+    %w[--example -e].each do |option|
+      describe option do
+        it "escapes the arg" do
+          options = Parser.parse([option, "this (and that)"])
+          expect(options[:full_description].length).to eq(1)
+          expect("this (and that)").to match(options[:full_description].first)
+        end
+      end
+    end
+
+    %w[--pattern -P].each do |option|
+      describe option do
+        it "sets the filename pattern" do
+          options = Parser.parse([option, 'spec/**/*.spec'])
+          expect(options[:pattern]).to eq('spec/**/*.spec')
+        end
+      end
+    end
+
+    %w[--tag -t].each do |option|
+      describe option do
+        context "without ~" do
+          it "treats no value as true" do
+            options = Parser.parse([option, 'foo'])
+            expect(options[:inclusion_filter]).to eq(:foo => true)
+          end
+
+          it "treats 'true' as true" do
+            options = Parser.parse([option, 'foo:true'])
+            expect(options[:inclusion_filter]).to eq(:foo => true)
+          end
+
+          it "treats 'nil' as nil" do
+            options = Parser.parse([option, 'foo:nil'])
+            expect(options[:inclusion_filter]).to eq(:foo => nil)
+          end
+
+          it "treats 'false' as false" do
+            options = Parser.parse([option, 'foo:false'])
+            expect(options[:inclusion_filter]).to eq(:foo => false)
+          end
+
+          it "merges muliple invocations" do
+            options = Parser.parse([option, 'foo:false', option, 'bar:true', option, 'foo:true'])
+            expect(options[:inclusion_filter]).to eq(:foo => true, :bar => true)
+          end
+
+          it "treats 'any_string' as 'any_string'" do
+            options = Parser.parse([option, 'foo:any_string'])
+            expect(options[:inclusion_filter]).to eq(:foo => 'any_string')
+          end
+
+          it "treats ':any_sym' as :any_sym" do
+            options = Parser.parse([option, 'foo::any_sym'])
+            expect(options[:inclusion_filter]).to eq(:foo => :any_sym)
+          end
+
+          it "treats '42' as 42" do
+            options = Parser.parse([option, 'foo:42'])
+            expect(options[:inclusion_filter]).to eq(:foo => 42)
+          end
+
+          it "treats '3.146' as 3.146" do
+            options = Parser.parse([option, 'foo:3.146'])
+            expect(options[:inclusion_filter]).to eq(:foo => 3.146)
+          end
+        end
+
+        context "with ~" do
+          it "treats no value as true" do
+            options = Parser.parse([option, '~foo'])
+            expect(options[:exclusion_filter]).to eq(:foo => true)
+          end
+
+          it "treats 'true' as true" do
+            options = Parser.parse([option, '~foo:true'])
+            expect(options[:exclusion_filter]).to eq(:foo => true)
+          end
+
+          it "treats 'nil' as nil" do
+            options = Parser.parse([option, '~foo:nil'])
+            expect(options[:exclusion_filter]).to eq(:foo => nil)
+          end
+
+          it "treats 'false' as false" do
+            options = Parser.parse([option, '~foo:false'])
+            expect(options[:exclusion_filter]).to eq(:foo => false)
+          end
+        end
+      end
+    end
+
+    describe "--order" do
+      it "is nil by default" do
+        expect(Parser.parse([])[:order]).to be_nil
+      end
+
+      %w[rand random].each do |option|
+        context "with #{option}" do
+          it "defines the order as random" do
+            options = Parser.parse(['--order', option])
+            expect(options[:order]).to eq(option)
+          end
+        end
+      end
+    end
+
+    describe "--seed" do
+      it "sets the order to rand:SEED" do
+        options = Parser.parse(%w[--seed 123])
+        expect(options[:order]).to eq("rand:123")
+      end
+    end
+
+    describe '--profile' do
+      it 'sets profile_examples to true by default' do
+        options = Parser.parse(%w[--profile])
+        expect(options[:profile_examples]).to eq true
+      end
+
+      it 'sets profile_examples to supplied int' do
+        options = Parser.parse(%w[--profile 10])
+        expect(options[:profile_examples]).to eq 10
+      end
+
+      it 'sets profile_examples to true when accidentally combined with path' do
+        allow_warning
+        options = Parser.parse(%w[--profile some/path])
+        expect(options[:profile_examples]).to eq true
+      end
+
+      it 'warns when accidentally combined with path' do
+        expect_warning_without_call_site "Non integer specified as profile count"
+        options = Parser.parse(%w[--profile some/path])
+        expect(options[:profile_examples]).to eq true
+      end
+    end
+
+    describe '--warning' do
+      around do |ex|
+        verbose = $VERBOSE
+        ex.run
+        $VERBOSE = verbose
+      end
+
+      it 'immediately enables warnings so that warnings are issued for files loaded by `--require`' do
+        $VERBOSE = false
+
+        expect {
+          Parser.parse(%w[--warnings])
+        }.to change { $VERBOSE }.from(false).to(true)
+      end
+    end
+
+  end
+end
diff --git a/rspec-core/spec/rspec/core/ordering_spec.rb b/rspec-core/spec/rspec/core/ordering_spec.rb
new file mode 100644
index 0000000..2cda655
--- /dev/null
+++ b/rspec-core/spec/rspec/core/ordering_spec.rb
@@ -0,0 +1,100 @@
+module RSpec
+  module Core
+    module Ordering
+      RSpec.describe Identity do
+        it "does not affect the ordering of the items" do
+          expect(Identity.new.order([1, 2, 3])).to eq([1, 2, 3])
+        end
+      end
+
+      RSpec.describe Random do
+        describe '.order' do
+          subject { described_class.new(configuration) }
+
+          let(:configuration)  { RSpec::Core::Configuration.new }
+          let(:items)          { 10.times.map { |n| n } }
+          let(:shuffled_items) { subject.order items }
+
+          it 'shuffles the items randomly' do
+            expect(shuffled_items).to match_array items
+            expect(shuffled_items).to_not eq items
+          end
+
+          context 'given multiple calls' do
+            it 'returns the items in the same order' do
+              expect(subject.order(items)).to eq shuffled_items
+            end
+          end
+
+          context 'given randomization has been seeded explicitly' do
+            before { @seed = srand }
+            after  { srand @seed }
+
+            it "does not affect the global random number generator" do
+              srand 123
+              val1, val2 = rand(1_000), rand(1_000)
+
+              subject
+
+              srand 123
+              subject.order items
+              expect(rand(1_000)).to eq(val1)
+              subject.order items
+              expect(rand(1_000)).to eq(val2)
+            end
+          end
+        end
+      end
+
+      RSpec.describe Custom do
+        it 'uses the block to order the list' do
+          strategy = Custom.new(proc { |list| list.reverse })
+
+          expect(strategy.order([1, 2, 3, 4])).to eq([4, 3, 2, 1])
+        end
+      end
+
+      RSpec.describe Registry do
+        let(:configuration) { Configuration.new }
+        subject(:registry) { Registry.new(configuration) }
+
+        describe "#used_random_seed?" do
+          it 'returns false if the random orderer has not been used' do
+            expect(registry.used_random_seed?).to be false
+          end
+
+          it 'returns false if the random orderer has been fetched but not used' do
+            expect(registry.fetch(:random)).to be_a(Random)
+            expect(registry.used_random_seed?).to be false
+          end
+
+          it 'returns true if the random orderer has been used' do
+            registry.fetch(:random).order([1, 2])
+            expect(registry.used_random_seed?).to be true
+          end
+        end
+
+        describe "#fetch" do
+          it "gives the registered ordering when called with a symbol" do
+            ordering = Object.new
+            subject.register(:falcon, ordering)
+
+            expect(subject.fetch(:falcon)).to be ordering
+          end
+
+          context "when given an unrecognized symbol" do
+            it 'invokes the given block and returns its value' do
+              expect(subject.fetch(:falcon) { :fallback }).to eq(:fallback)
+            end
+
+            it 'raises an error if no block is given' do
+              expect {
+                subject.fetch(:falcon)
+              }.to raise_error(IndexError)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/pending_example_spec.rb b/rspec-core/spec/rspec/core/pending_example_spec.rb
new file mode 100644
index 0000000..5e2f25e
--- /dev/null
+++ b/rspec-core/spec/rspec/core/pending_example_spec.rb
@@ -0,0 +1,221 @@
+RSpec.describe "an example" do
+  context "declared pending with metadata" do
+    it "uses the value assigned to :pending as the message" do
+      group = RSpec.describe('group') do
+        example "example", :pending => 'just because' do
+          fail
+        end
+      end
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(example).to be_pending_with('just because')
+    end
+
+    it "sets the message to 'No reason given' if :pending => true" do
+      group = RSpec.describe('group') do
+        example "example", :pending => true do
+          fail
+        end
+      end
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(example).to be_pending_with('No reason given')
+    end
+
+    it "passes if a mock expectation is not satisifed" do
+      group = RSpec.describe('group') do
+        example "example", :pending => "because" do
+          expect(RSpec).to receive(:a_message_in_a_bottle)
+        end
+      end
+
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(example).to be_pending_with('because')
+      expect(example.execution_result.status).to eq(:pending)
+    end
+
+    it "does not mutate the :pending attribute of the user metadata when handling mock expectation errors" do
+      group = RSpec.describe('group') do
+        example "example", :pending => "because" do
+          expect(RSpec).to receive(:a_message_in_a_bottle)
+        end
+      end
+
+      group.run
+      example = group.examples.first
+      expect(example.metadata[:pending]).to be_truthy
+    end
+  end
+
+  context "made pending with `define_derived_metadata`" do
+    before do
+      RSpec.configure do |config|
+        config.define_derived_metadata(:not_ready) do |meta|
+          meta[:pending] ||= "Not ready"
+        end
+      end
+    end
+
+    it 'has a pending result if there is an error' do
+      group = RSpec.describe "group" do
+        example "something", :not_ready do
+          boom
+        end
+      end
+
+      group.run
+      example = group.examples.first
+      expect(example).to be_pending_with("Not ready")
+    end
+
+    it 'fails if there is no error' do
+      group = RSpec.describe "group" do
+        example "something", :not_ready do
+        end
+      end
+
+      group.run
+      example = group.examples.first
+      expect(example.execution_result.status).to be(:failed)
+      expect(example.execution_result.exception.message).to include("Expected example to fail")
+    end
+  end
+
+  context "with no block" do
+    it "is listed as pending with 'Not yet implemented'" do
+      group = RSpec.describe('group') do
+        it "has no block"
+      end
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(example).to be_skipped_with('Not yet implemented')
+    end
+  end
+
+  context "with no args" do
+    it "is listed as pending with the default message" do
+      group = RSpec.describe('group') do
+        it "does something" do
+          pending
+          fail
+        end
+      end
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(example).to be_pending_with(RSpec::Core::Pending::NO_REASON_GIVEN)
+    end
+
+    it "fails when the rest of the example passes" do
+      called = false
+      group = RSpec.describe('group') do
+        it "does something" do
+          pending
+          called = true
+        end
+      end
+
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(called).to eq(true)
+      result = example.execution_result
+      expect(result.pending_fixed).to eq(true)
+      expect(result.status).to eq(:failed)
+    end
+
+    it "does not mutate the :pending attribute of the user metadata when the rest of the example passes" do
+      group = RSpec.describe('group') do
+        it "does something" do
+          pending
+        end
+      end
+
+      group.run
+      example = group.examples.first
+      expect(example.metadata).to include(:pending => true)
+    end
+  end
+
+  context "with no docstring" do
+    context "declared with the pending method" do
+      it "has an auto-generated description if it has an expectation" do
+        ex = nil
+
+        RSpec.describe('group') do
+          it "checks something" do
+            expect((3+4)).to eq(7)
+          end
+          ex = pending do
+            expect("string".reverse).to eq("gnirts")
+          end
+        end.run
+
+        expect(ex.description).to eq('should eq "gnirts"')
+      end
+    end
+
+    context "after another example with some assertion" do
+      it "does not show any message" do
+        ex = nil
+
+        RSpec.describe('group') do
+          it "checks something" do
+            expect((3+4)).to eq(7)
+          end
+          ex = specify do
+            pending
+          end
+        end.run
+
+        expect(ex.description).to match(/example at/)
+      end
+    end
+  end
+
+  context "with a message" do
+    it "is listed as pending with the supplied message" do
+      group = RSpec.describe('group') do
+        it "does something" do
+          pending("just because")
+          fail
+        end
+      end
+      example = group.examples.first
+      example.run(group.new, double.as_null_object)
+      expect(example).to be_pending_with('just because')
+    end
+  end
+
+  context "with a block" do
+    it "fails with an ArgumentError stating the syntax is deprecated" do
+      group = RSpec.describe('group') do
+        it "calls pending with a block" do
+          pending("with invalid syntax") do
+            :no_op
+          end
+          fail
+        end
+      end
+      example = group.examples.first
+      group.run
+      expect(example).to fail_with ArgumentError
+      expect(example.exception.message).to match(
+        /Passing a block within an example is now deprecated./
+      )
+    end
+
+    it "does not yield to the block" do
+      example_to_have_yielded = :did_not_yield
+      group = RSpec.describe('group') do
+        it "calls pending with a block" do
+          pending("just because") do
+            example_to_have_yielded = :pending_block
+          end
+          fail
+        end
+      end
+      group.run
+      expect(example_to_have_yielded).to eq :did_not_yield
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/pending_spec.rb b/rspec-core/spec/rspec/core/pending_spec.rb
new file mode 100644
index 0000000..8fe1631
--- /dev/null
+++ b/rspec-core/spec/rspec/core/pending_spec.rb
@@ -0,0 +1,6 @@
+RSpec.describe RSpec::Core::Pending do
+  it 'only defines methods that are part of the DSL' do
+    expect(RSpec::Core::Pending.instance_methods(false).map(&:to_sym)).to \
+      match_array([:pending, :skip])
+  end
+end
diff --git a/rspec-core/spec/rspec/core/project_initializer_spec.rb b/rspec-core/spec/rspec/core/project_initializer_spec.rb
new file mode 100644
index 0000000..2ae9467
--- /dev/null
+++ b/rspec-core/spec/rspec/core/project_initializer_spec.rb
@@ -0,0 +1,122 @@
+require 'rspec/core/project_initializer'
+
+module RSpec::Core
+  RSpec.describe ProjectInitializer, :isolated_directory => true do
+
+    describe "#run" do
+      context "with no args" do
+        subject(:command_line_config) { ProjectInitializer.new(:report_stream => output) }
+
+        let(:output) { StringIO.new }
+
+        context "with no .rspec file" do
+          it "says it's creating .rspec " do
+            expect{ command_line_config.run }.to change{
+              output.rewind
+              output.read
+            }.to(include 'create   .rspec')
+          end
+
+          it "generates a .rspec" do
+            command_line_config.run
+            expect(File.read('.rspec')).to match(/--color/m)
+          end
+        end
+
+        context "with a .rspec file" do
+          it "says .rspec exists" do
+            FileUtils.touch('.rspec')
+            expect{ command_line_config.run }.to change{
+              output.rewind
+              output.read
+            }.to(include 'exist   .rspec')
+          end
+
+          it "doesn't create a new one" do
+            File.open('.rspec', 'w') {|f| f << '--not-a-real-flag'}
+            command_line_config.run
+            expect(File.read('.rspec')).to eq('--not-a-real-flag')
+          end
+        end
+
+        context "with no spec/spec_helper.rb file" do
+          it "says it's creating spec/spec_helper.rb " do
+            expect{ command_line_config.run }.to change{
+              output.rewind
+              output.read
+            }.to(include 'create   spec/spec_helper.rb')
+          end
+
+          it "generates a spec/spec_helper.rb" do
+            command_line_config.run
+            expect(File.read('spec/spec_helper.rb')).to match(/RSpec\.configure do \|config\|/m)
+          end
+        end
+
+        context "with a spec/spec_helper.rb file" do
+          before { FileUtils.mkdir('spec') }
+
+          it "says spec/spec_helper.rb exists" do
+            FileUtils.touch('spec/spec_helper.rb')
+            expect{ command_line_config.run }.to change{
+              output.rewind
+              output.read
+            }.to(include 'exist   spec/spec_helper.rb')
+          end
+
+          it "doesn't create a new one" do
+            random_content = "content #{rand}"
+            File.open('spec/spec_helper.rb', 'w') {|f| f << random_content}
+            command_line_config.run
+            expect(File.read('spec/spec_helper.rb')).to eq(random_content)
+          end
+        end
+      end
+    end
+
+    describe "#run", "with a target directory" do
+      subject(:command_line_config) {
+        ProjectInitializer.new(:destination => tmpdir, :report_stream => StringIO.new)
+      }
+
+      let(:tmpdir) { 'relative/destination/' }
+
+      before { FileUtils.mkdir_p(tmpdir) }
+
+      context "with no .rspec file" do
+        it "generates a .rspec" do
+          command_line_config.run
+          expect(File.read(File.join(tmpdir, '.rspec'))).to match(/--color/m)
+        end
+      end
+
+      context "with a .rspec file" do
+        it "doesn't create a new one" do
+          dot_rspec_file = File.join(tmpdir, '.rspec')
+          File.open(dot_rspec_file, 'w') {|f| f << '--not-a-real-flag'}
+          command_line_config.run
+          expect(File.read(dot_rspec_file)).to eq('--not-a-real-flag')
+        end
+      end
+
+      context "with no spec/spec_helper.rb file" do
+        it "generates a spec/spec_helper.rb" do
+          command_line_config.run
+          expect(File.read(File.join(tmpdir, 'spec/spec_helper.rb'))).to match(/RSpec\.configure do \|config\|/m)
+        end
+      end
+
+      context "with a spec/spec_helper.rb file" do
+        it "doesn't create a new one" do
+          FileUtils.mkdir File.join(tmpdir, 'spec')
+          spec_helper_file = File.join(tmpdir, 'spec', 'spec_helper.rb')
+          random_content = "content #{rand}"
+          File.open(spec_helper_file, 'w') {|f| f << random_content}
+          command_line_config.run
+          expect(File.read(spec_helper_file)).to eq(random_content)
+        end
+      end
+    end
+
+  end
+end
diff --git a/rspec-core/spec/rspec/core/rake_task_spec.rb b/rspec-core/spec/rspec/core/rake_task_spec.rb
new file mode 100644
index 0000000..772dea4
--- /dev/null
+++ b/rspec-core/spec/rspec/core/rake_task_spec.rb
@@ -0,0 +1,401 @@
+require "rspec/core/rake_task"
+require 'tempfile'
+
+module RSpec::Core
+  RSpec.describe RakeTask do
+    let(:task) { RakeTask.new }
+
+    def ruby
+      FileUtils::RUBY
+    end
+
+    def spec_command
+      task.__send__(:spec_command)
+    end
+
+    context "with a name passed to the constructor" do
+      let(:task) { RakeTask.new(:task_name) }
+
+      it "correctly sets the name" do
+        expect(task.name).to eq :task_name
+      end
+    end
+
+    context "with args passed to the rake task" do
+      it "correctly passes along task arguments" do
+        the_task = RakeTask.new(:rake_task_args, :files) do |t, args|
+          expect(args[:files]).to eq "first_spec.rb"
+        end
+
+        expect(the_task).to receive(:run_task) { true }
+        expect(Rake.application.invoke_task("rake_task_args[first_spec.rb]")).to be_truthy
+      end
+    end
+
+    default_load_path_opts = '-I\S+'
+
+    context "default" do
+      it "renders rspec" do
+        expect(spec_command).to match(/^#{ruby} #{default_load_path_opts} '?#{task.rspec_path}'?/)
+      end
+    end
+
+    context "with space", :unless => RSpec::Support::OS.windows? do
+      it "renders rspec with space escaped" do
+        task.rspec_path = '/path with space/exe/rspec'
+        expect(spec_command).to match(/^#{ruby} #{default_load_path_opts} \/path\\ with\\ space\/exe\/rspec/)
+      end
+    end
+
+    context "with ruby options" do
+      it "renders them before the rspec path" do
+        task.ruby_opts = "-w"
+        expect(spec_command).to match(/^#{ruby} -w #{default_load_path_opts} '?#{task.rspec_path}'?/)
+      end
+    end
+
+    context "with rspec_opts" do
+      it "adds the rspec_opts" do
+        task.rspec_opts = "-Ifoo"
+        expect(spec_command).to match(/#{task.rspec_path}.*-Ifoo/)
+      end
+    end
+
+    context "with pattern" do
+      it "adds the pattern" do
+        task.pattern = "complex_pattern"
+        expect(spec_command).to match(/ --pattern '?complex_pattern'?/)
+      end
+
+      it "shellescapes the pattern as necessary", :unless => RSpec::Support::OS.windows? do
+        task.pattern = "foo'bar"
+        expect(spec_command).to include(" --pattern foo\\'bar")
+      end
+    end
+
+    context 'with custom exit status' do
+      def silence_output(&block)
+        expect(&block).to output(anything).to_stdout.and output(anything).to_stderr
+      end
+
+      it 'returns the correct status on exit', :slow do
+        expect(task).to receive(:exit).with(2)
+
+        silence_output do
+          task.ruby_opts = '-e "exit(2);" ;#'
+          task.run_task true
+        end
+      end
+    end
+
+    context 'with verbose enabled' do
+      it 'prints the command only to stdout for passing specs', :slow do
+        expect {
+          task.ruby_opts = '-e ""'
+          task.run_task true
+        }.to output(/-e ""/).to_stdout.and avoid_outputting.to_stderr
+      end
+
+      it 'prints an additional message to stderr for failures', :slow do
+        allow(task).to receive(:exit)
+
+        expect {
+          task.ruby_opts = '-e "exit(1);" ;#'
+          task.run_task true
+        }.to output(/-e "exit\(1\);" ;#/).to_stdout.and output(/-e "exit\(1\);".* failed/).to_stderr
+      end
+    end
+
+    context 'with verbose disabled' do
+      it 'does not print to stdout or stderr', :slow do
+        allow(task).to receive(:exit)
+
+        expect {
+          task.ruby_opts = '-e "exit(1);" ;#'
+          task.run_task false
+        }.to avoid_outputting.to_stdout.and avoid_outputting.to_stderr
+      end
+    end
+
+    def loaded_files
+      args = Shellwords.split(spec_command)
+      args -= [task.class::RUBY, "-S", task.rspec_path]
+      config = Configuration.new
+      config_options = ConfigurationOptions.new(args)
+      config_options.configure(config)
+      config.files_to_run
+    end
+
+    def specify_consistent_ordering_of_files_to_run(pattern, file_searcher)
+      orderings = [
+        %w[ a/1.rb a/2.rb a/3.rb ],
+        %w[ a/2.rb a/1.rb a/3.rb ],
+        %w[ a/3.rb a/2.rb a/1.rb ]
+      ].map do |files|
+        allow(file_searcher).to receive(:[]).with(anything).and_call_original
+        expect(file_searcher).to receive(:[]).with(a_string_including pattern) { files }
+        loaded_files
+      end
+
+      expect(orderings.uniq.size).to eq(1)
+    end
+
+    context "with SPEC env var set" do
+      it "sets files to run" do
+        with_env_vars 'SPEC' => 'path/to/file' do
+          expect(loaded_files).to eq(["path/to/file"])
+        end
+      end
+
+      it "sets the files to run in a consistent order, regardless of the underlying FileList ordering" do
+        with_env_vars 'SPEC' => 'a/*.rb' do
+          specify_consistent_ordering_of_files_to_run('a/*.rb', FileList)
+        end
+      end
+    end
+
+    describe "load path manipulation" do
+      def self.it_configures_rspec_load_path(description, path_template)
+        context "when rspec is installed as #{description}" do
+          # Matchers are lazily loaded via `autoload`, so we need to get the matcher before
+          # the load path is manipulated, so we're using `let!` here to do that.
+          let!(:include_expected_load_path_option) do
+            match(/ -I'?#{path_template % "rspec-core"}'?#{File::PATH_SEPARATOR}'?#{path_template % "rspec-support"}'? /)
+          end
+
+          it "adds the current rspec-core and rspec-support dirs to the load path to ensure the current version is used" do
+            $LOAD_PATH.replace([
+              path_template % "rspec-core",
+              path_template % "rspec-support",
+              path_template % "rspec-expectations",
+              path_template % "rspec-mocks",
+              path_template % "rake"
+            ])
+
+            expect(spec_command).to include_expected_load_path_option
+          end
+
+          it "avoids adding the same load path entries twice" do
+            $LOAD_PATH.replace([
+              path_template % "rspec-core",
+              path_template % "rspec-support",
+              path_template % "rspec-core",
+              path_template % "rspec-support"
+            ])
+
+            expect(spec_command).to include_expected_load_path_option
+          end
+        end
+      end
+
+      it_configures_rspec_load_path "bundler :git dependencies",
+        "/Users/myron/code/some-gem/bundle/ruby/2.1.0/bundler/gems/%s-8d2e4e570994/lib"
+
+      it_configures_rspec_load_path "bundler :path dependencies",
+        "/Users/myron/code/rspec-dev/repos/%s/lib"
+
+      it_configures_rspec_load_path "a rubygem",
+        "/Users/myron/.gem/ruby/1.9.3/gems/%s-3.1.0.beta1/lib"
+
+      it "does not include extra load path entries for other gems that have `rspec-core` in its path" do
+        # matchers are lazily loaded with autoload, so we need to get the matcher before manipulating the load path.
+        include_extra_load_path_entries = include("simplecov", "minitest", "rspec-core/spec")
+
+        # these are items on my load path due to `bundle install --standalone`,
+        # and my initial logic caused all these to be included in the `-I` option.
+        $LOAD_PATH.replace([
+           "/Users/user/code/rspec-dev/repos/rspec-core/spec",
+           "/Users/user/code/rspec-dev/repos/rspec-core/bundle/ruby/1.9.1/gems/simplecov-0.8.2/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-core/bundle/ruby/1.9.1/gems/simplecov-html-0.8.0/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-core/bundle/ruby/1.9.1/gems/minitest-5.3.3/lib",
+           "/Users/user/code/rspec-dev/repos/rspec/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-mocks/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-core/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-expectations/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-support/lib",
+           "/Users/user/code/rspec-dev/repos/rspec-core/bundle",
+        ])
+
+        expect(spec_command).not_to include_extra_load_path_entries
+      end
+    end
+
+    it "sets the files to run in a consistent order, regardless of the underlying FileList ordering" do
+      task.pattern = 'a/*.rb'
+      specify_consistent_ordering_of_files_to_run('a/*.rb', Dir)
+    end
+
+    context "with a pattern value" do
+      context "that matches no files" do
+        it "runs nothing" do
+          task.pattern = 'a/*.no_match'
+          expect(loaded_files).to eq([])
+        end
+      end
+
+      context "that is an existing directory, not a file glob" do
+        it "loads the spec files in that directory" do
+          task.pattern = "./spec/rspec/core/resources/acceptance"
+          expect(loaded_files).to contain_files("./spec/rspec/core/resources/acceptance/foo_spec.rb")
+        end
+      end
+
+      context "that is an existing file, not a file glob" do
+        it "loads the spec file" do
+          task.pattern = "./spec/rspec/core/resources/acceptance/foo_spec.rb"
+          expect(loaded_files).to contain_files("./spec/rspec/core/resources/acceptance/foo_spec.rb")
+        end
+      end
+
+      context "that is an absolute path file glob" do
+        it "loads the matching spec files", :failing_on_appveyor,
+        :pending => false,
+        :skip => (ENV['APPVEYOR'] ? "Failing on AppVeyor but :pending isn't working for some reason" : false) do
+          dir = File.expand_path("../resources", __FILE__)
+          task.pattern = File.join(dir, "**/*_spec.rb")
+
+          expect(loaded_files).to contain_files(
+            "./spec/rspec/core/resources/acceptance/foo_spec.rb",
+            "./spec/rspec/core/resources/a_spec.rb"
+          )
+        end
+      end
+
+      context "that is a relative file glob, for a path not under the default spec dir (`spec`)" do
+        it "loads the matching spec files" do
+          Dir.chdir("./spec/rspec/core") do
+            task.pattern = "resources/**/*_spec.rb"
+
+            expect(loaded_files).to contain_files(
+              "resources/acceptance/foo_spec.rb",
+              "resources/a_spec.rb"
+            )
+          end
+        end
+      end
+
+      context "that is an array of existing files or directories, not a file glob" do
+        it "loads the specified spec files, and spec files from the specified directories" do
+          task.pattern = ["./spec/rspec/core/resources/acceptance",
+                          "./spec/rspec/core/resources/a_bar.rb"]
+
+          expect(loaded_files).to contain_files(
+            "./spec/rspec/core/resources/acceptance/foo_spec.rb",
+            "./spec/rspec/core/resources/a_bar.rb"
+          )
+        end
+      end
+
+      # https://github.com/rspec/rspec-core/issues/1695
+      context "that is a single glob that starts with ./" do
+        it "loads the spec files that match the glob" do
+          task.pattern = "./spec/rspec/core/resources/acceptance/**/*_spec.rb"
+          expect(loaded_files).to contain_files("./spec/rspec/core/resources/acceptance/foo_spec.rb")
+        end
+      end
+
+      context "that is an array of globs relative to the current working dir" do
+        it "loads spec files that match any of the globs" do
+          task.pattern = ["./spec/rspec/core/resources/acceptance/*_spec.rb",
+                          "./spec/rspec/core/resources/*_bar.rb"]
+
+          expect(loaded_files).to contain_files(
+            "./spec/rspec/core/resources/acceptance/foo_spec.rb",
+            "./spec/rspec/core/resources/a_bar.rb"
+          )
+        end
+      end
+
+      context "that is a mixture of file globs and individual files or dirs" do
+        it "loads all specified or matching files" do
+          task.pattern = ["./spec/rspec/core/resources/acceptance/*_spec.rb",
+                          "./spec/rspec/core/resources/a_bar.rb"]
+
+          expect(loaded_files).to contain_files(
+            "./spec/rspec/core/resources/acceptance/foo_spec.rb",
+            "./spec/rspec/core/resources/a_bar.rb"
+          )
+        end
+      end
+
+      context "that is a FileList" do
+        it "loads the files from the FileList" do
+          task.pattern = FileList["spec/rspec/core/resources/**/*_spec.rb"]
+
+          expect(loaded_files).to contain_exactly(
+            "spec/rspec/core/resources/a_spec.rb",
+            "spec/rspec/core/resources/acceptance/foo_spec.rb"
+          )
+        end
+      end
+    end
+
+    context "without an exclude_pattern" do
+      it 'does not pass the --exclude-pattern option' do
+        expect(spec_command).not_to include("exclude")
+      end
+    end
+
+    context "with an exclude_pattern" do
+      include_context "isolated directory"
+
+      def make_file(dir, name)
+        File.join("spec", dir, name).tap { |f| FileUtils.touch(f) }
+      end
+
+      def make_files_in_dir(dir)
+        %w[ foo_spec.rb bar_spec.rb ].map do |file_name|
+          make_file(dir, file_name)
+        end
+      end
+
+      before do
+        spec_dir = File.join(Dir.getwd, "spec")
+        task.exclude_pattern = "spec/acceptance/*_spec.rb"
+
+        FileUtils.mkdir_p(File.join(spec_dir, "acceptance"))
+        FileUtils.mkdir_p(File.join(spec_dir, "unit"))
+
+        make_files_in_dir "acceptance"
+      end
+
+      it "shellescapes the pattern as necessary", :unless => RSpec::Support::OS.windows? do
+        task.exclude_pattern = "foo'bar"
+        expect(spec_command).to include(" --exclude-pattern foo\\'bar")
+      end
+
+      it "it does not load matching files" do
+        task.pattern = "spec/**/*_spec.rb"
+        unit_files = make_files_in_dir "unit"
+
+        expect(loaded_files).to contain_files(*unit_files)
+      end
+
+      it "excludes files when pattern and exclusion_pattern don't consistently start with ./" do
+        task.exclude_pattern = "./spec/acceptance/*_spec.rb"
+        task.pattern = "spec/**/*_spec.rb"
+        unit_files = make_files_in_dir "unit"
+
+        expect(loaded_files).to contain_files(*unit_files)
+      end
+    end
+
+    context "with paths with quotes or spaces" do
+      include_context "isolated directory"
+
+      it "matches files with quotes and spaces", :failing_on_appveyor do
+        spec_dir = File.join(Dir.getwd, "spec")
+        task.pattern = "spec/*spec.rb"
+        FileUtils.mkdir_p(spec_dir)
+
+        files = ["first_spec.rb", "second_\"spec.rb", "third_\'spec.rb", "fourth spec.rb"].map do |file_name|
+          File.join("spec", file_name).tap { |f| FileUtils.touch(f) }
+        end
+
+        expect(loaded_files).to contain_files(*files)
+      end
+    end
+
+    it_behaves_like "handling symlinked directories when loading spec files"
+  end
+end
diff --git a/rspec-core/spec/rspec/core/random_spec.rb b/rspec-core/spec/rspec/core/random_spec.rb
new file mode 100644
index 0000000..f1e8ea9
--- /dev/null
+++ b/rspec-core/spec/rspec/core/random_spec.rb
@@ -0,0 +1,45 @@
+module RSpec
+  module Core
+    RSpec.describe RandomNumberGenerator do
+      it 'is a random number generator' do
+        random = described_class.new
+
+        expect([Fixnum, Bignum]).to include random.seed.class
+        expect(random.rand).to be_a Float
+
+        rands = []
+        100.times do
+          rands << random.rand
+        end
+
+        expect(rands.uniq.count).to be > 90
+      end
+
+      it 'produces the same results given the same seed' do
+        seed = rand(999)
+
+        random = described_class.new(seed)
+
+        expect(random.seed).to eq seed
+
+        expected = []
+        5.times do
+          expected << random.rand(999)
+        end
+
+        10.times do
+          random = described_class.new(seed)
+
+          expect(random.seed).to eq seed
+
+          actual = []
+          5.times do
+            actual << random.rand(999)
+          end
+
+          expect(actual).to eq expected
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/reporter_spec.rb b/rspec-core/spec/rspec/core/reporter_spec.rb
new file mode 100644
index 0000000..2cb45d6
--- /dev/null
+++ b/rspec-core/spec/rspec/core/reporter_spec.rb
@@ -0,0 +1,209 @@
+module RSpec::Core
+  RSpec.describe Reporter do
+    include FormatterSupport
+
+    let(:config)   { Configuration.new }
+    let(:reporter) { Reporter.new config }
+    let(:start_time) { Time.now }
+    let(:example) { super() }
+
+    describe "finish" do
+      let(:formatter) { double("formatter") }
+
+      %w[start_dump dump_pending dump_failures dump_summary close].map(&:to_sym).each do |message|
+        it "sends #{message} to the formatter(s) that respond to message" do
+          reporter.register_listener formatter, message
+          expect(formatter.as_null_object).to receive(message)
+          reporter.finish
+        end
+
+        it "doesnt notify formatters about messages they dont implement" do
+          expect { reporter.finish }.to_not raise_error
+        end
+      end
+
+      it "dumps the failure summary after the profile and deprecation summary so failures don't scroll off the screen and get missed" do
+        config.profile_examples = 10
+        formatter = instance_double("RSpec::Core::Formatter::ProgressFormatter")
+        reporter.register_listener(formatter, :dump_summary, :dump_profile, :deprecation_summary)
+
+        expect(formatter).to receive(:deprecation_summary).ordered
+        expect(formatter).to receive(:dump_profile).ordered
+        expect(formatter).to receive(:dump_summary).ordered
+
+        reporter.finish
+      end
+    end
+
+    describe 'start' do
+      before { config.start_time = start_time }
+
+      it 'notifies the formatter of start with example count' do
+        formatter = double("formatter")
+        reporter.register_listener formatter, :start
+
+        expect(formatter).to receive(:start) do |notification|
+          expect(notification.count).to eq 3
+          expect(notification.load_time).to eq 5
+        end
+
+        reporter.start 3, (start_time + 5)
+      end
+
+      it 'notifies the formatter of the seed used before notifing of start' do
+        formatter = double("formatter")
+        reporter.register_listener formatter, :seed
+        reporter.register_listener formatter, :start
+        expect(formatter).to receive(:seed).ordered.with(
+          an_object_having_attributes(:seed => config.seed, :seed_used? => config.seed_used?)
+        )
+        expect(formatter).to receive(:start).ordered
+        reporter.start 1
+      end
+    end
+
+    context "given one formatter" do
+      it "passes messages to that formatter" do
+        formatter = double("formatter", :example_started => nil)
+        reporter.register_listener formatter, :example_started
+
+        expect(formatter).to receive(:example_started) do |notification|
+          expect(notification.example).to eq example
+        end
+
+        reporter.example_started(example)
+      end
+
+      it "passes example_group_started and example_group_finished messages to that formatter in that order" do
+        order = []
+
+        formatter = double("formatter")
+        allow(formatter).to receive(:example_group_started)  { |n| order << "Started: #{n.group.description}" }
+        allow(formatter).to receive(:example_group_finished) { |n| order << "Finished: #{n.group.description}" }
+
+        reporter.register_listener formatter, :example_group_started, :example_group_finished
+
+        group = RSpec.describe("root")
+        group.describe("context 1") do
+          example("ignore") {}
+        end
+        group.describe("context 2") do
+          example("ignore") {}
+        end
+
+        group.run(reporter)
+
+        expect(order).to eq([
+           "Started: root",
+           "Started: context 1",
+           "Finished: context 1",
+           "Started: context 2",
+           "Finished: context 2",
+           "Finished: root"
+        ])
+      end
+    end
+
+    context "given an example group with no examples" do
+      it "does not pass example_group_started or example_group_finished to formatter" do
+        formatter = double("formatter")
+        expect(formatter).not_to receive(:example_group_started)
+        expect(formatter).not_to receive(:example_group_finished)
+
+        reporter.register_listener formatter, :example_group_started, :example_group_finished
+
+        group = RSpec.describe("root")
+
+        group.run(reporter)
+      end
+    end
+
+    context "given multiple formatters" do
+      it "passes messages to all formatters" do
+        formatters = (1..2).map { double("formatter", :example_started => nil) }
+
+        formatters.each do |formatter|
+          expect(formatter).to receive(:example_started) do |notification|
+            expect(notification.example).to eq example
+          end
+          reporter.register_listener formatter, :example_started
+        end
+
+        reporter.example_started(example)
+      end
+    end
+
+    describe "#report" do
+      it "supports one arg (count)" do
+        reporter.report(1) {}
+      end
+
+      it "yields itself" do
+        yielded = nil
+        reporter.report(3) { |r| yielded = r }
+        expect(yielded).to eq(reporter)
+      end
+    end
+
+    describe "#register_listener" do
+      let(:listener) { double("listener", :start => nil) }
+
+      before { reporter.register_listener listener, :start }
+
+      it 'will register the listener to specified notifications' do
+        expect(reporter.registered_listeners :start).to eq [listener]
+      end
+
+      it 'will match string notification names' do
+        reporter.register_listener listener, "stop"
+        expect(reporter.registered_listeners :stop).to eq [listener]
+      end
+
+      it 'will send notifications when a subscribed event is triggered' do
+        expect(listener).to receive(:start) do |notification|
+          expect(notification.count).to eq 42
+        end
+        reporter.start 42
+      end
+
+      it 'will ignore duplicated listeners' do
+        reporter.register_listener listener, :start
+        expect(listener).to receive(:start).once
+        reporter.start 42
+      end
+    end
+
+    describe "timing" do
+      before do
+        config.start_time = start_time
+      end
+
+      it "uses RSpec::Core::Time as to not be affected by changes to time in examples" do
+        formatter = double(:formatter)
+        reporter.register_listener formatter, :dump_summary
+        reporter.start 1
+        allow(Time).to receive_messages(:now => ::Time.utc(2012, 10, 1))
+
+        duration = nil
+        allow(formatter).to receive(:dump_summary) do |notification|
+          duration = notification.duration
+        end
+
+        reporter.finish
+        expect(duration).to be < 0.2
+      end
+
+      it "captures the load time so it can report it later" do
+        formatter = instance_double("ProgressFormatter")
+        reporter.register_listener formatter, :dump_summary
+        reporter.start 3, (start_time + 5)
+
+        expect(formatter).to receive(:dump_summary) do |notification|
+          expect(notification.load_time).to eq(5)
+        end
+
+        reporter.finish
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/resources/a_bar.rb b/rspec-core/spec/rspec/core/resources/a_bar.rb
new file mode 100644
index 0000000..e69de29
diff --git a/rspec-core/spec/rspec/core/resources/a_foo.rb b/rspec-core/spec/rspec/core/resources/a_foo.rb
new file mode 100644
index 0000000..e69de29
diff --git a/rspec-core/spec/rspec/core/resources/a_spec.rb b/rspec-core/spec/rspec/core/resources/a_spec.rb
new file mode 100644
index 0000000..6503624
--- /dev/null
+++ b/rspec-core/spec/rspec/core/resources/a_spec.rb
@@ -0,0 +1 @@
+# Empty - used by ../options_spec.rb
diff --git a/rspec-core/spec/rspec/core/resources/acceptance/bar.rb b/rspec-core/spec/rspec/core/resources/acceptance/bar.rb
new file mode 100644
index 0000000..e69de29
diff --git a/rspec-core/spec/rspec/core/resources/acceptance/foo_spec.rb b/rspec-core/spec/rspec/core/resources/acceptance/foo_spec.rb
new file mode 100644
index 0000000..e69de29
diff --git a/rspec-core/spec/rspec/core/resources/custom_example_group_runner.rb b/rspec-core/spec/rspec/core/resources/custom_example_group_runner.rb
new file mode 100644
index 0000000..40e4c2b
--- /dev/null
+++ b/rspec-core/spec/rspec/core/resources/custom_example_group_runner.rb
@@ -0,0 +1,14 @@
+module Custom
+  class ExampleGroupRunner
+    attr_reader :options, :arg
+    def initialize(options, arg)
+      @options, @arg = options, arg
+    end
+
+    def load_files(files)
+    end
+
+    def run
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/resources/formatter_specs.rb b/rspec-core/spec/rspec/core/resources/formatter_specs.rb
new file mode 100644
index 0000000..cdf4783
--- /dev/null
+++ b/rspec-core/spec/rspec/core/resources/formatter_specs.rb
@@ -0,0 +1,58 @@
+# Deliberately named _specs.rb to avoid being loaded except when specified
+
+RSpec.describe "pending spec with no implementation" do
+  it "is pending"
+end
+
+RSpec.describe "pending command with block format" do
+  context "with content that would fail" do
+    it "is pending" do
+      pending
+      expect(1).to eq(2)
+    end
+  end
+
+  context "with content that would pass" do
+    it "fails" do
+      pending
+      expect(1).to eq(1)
+    end
+  end
+end
+
+RSpec.describe "passing spec" do
+  it "passes" do
+    expect(1).to eq(1)
+  end
+end
+
+RSpec.describe "failing spec" do
+  it "fails" do
+    expect(1).to eq(2)
+  end
+end
+
+RSpec.describe "a failing spec with odd backtraces" do
+  it "fails with a backtrace that has no file" do
+    require 'erb'
+
+    ERB.new("<%= raise 'foo' %>").result
+  end
+
+  it "fails with a backtrace containing an erb file" do
+    e = Exception.new
+
+    def e.backtrace
+      ["/foo.html.erb:1:in `<main>': foo (RuntimeError)",
+        "   from /lib/ruby/1.9.1/erb.rb:753:in `eval'"]
+    end
+
+    def e.message
+      # Redefining message steps around this behaviour
+      # on JRuby: http://jira.codehaus.org/browse/JRUBY-5637
+      self.class.name
+    end
+
+    raise e
+  end
+end
diff --git a/rspec-core/spec/rspec/core/resources/utf8_encoded.rb b/rspec-core/spec/rspec/core/resources/utf8_encoded.rb
new file mode 100644
index 0000000..b173bce
--- /dev/null
+++ b/rspec-core/spec/rspec/core/resources/utf8_encoded.rb
@@ -0,0 +1,9 @@
+# encoding: utf-8
+module Custom
+  class ExampleUTF8ClassNameVarietà
+    def self.è
+      così = :però
+      così
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/rspec_matchers_spec.rb b/rspec-core/spec/rspec/core/rspec_matchers_spec.rb
new file mode 100644
index 0000000..5640216
--- /dev/null
+++ b/rspec-core/spec/rspec/core/rspec_matchers_spec.rb
@@ -0,0 +1,43 @@
+module RSpec::Matchers
+  def __method_with_super
+    super
+  end
+
+  module ModThatIncludesMatchers
+    include RSpec::Matchers
+  end
+
+  RSpec.configure do |c|
+    c.include RSpec::Matchers, :include_rspec_matchers => true
+    c.include ModThatIncludesMatchers, :include_mod_that_includes_rspec_matchers => true
+  end
+
+  RSpec.describe self do
+    shared_examples_for "a normal module with a method that supers" do
+      it "raises the expected error (and not SystemStackError)" do
+        expect { __method_with_super }.to raise_error(NoMethodError) # there is no __method_with_super in an ancestor
+      end
+    end
+
+    it_behaves_like "a normal module with a method that supers"
+
+    context "when RSpec::Matchers has been included in an example group" do
+      include RSpec::Matchers
+      it_behaves_like "a normal module with a method that supers"
+    end
+
+    context "when a module that includes RSpec::Matchers has been included in an example group" do
+      include RSpec::Matchers::ModThatIncludesMatchers
+      it_behaves_like "a normal module with a method that supers"
+    end
+
+    context "when RSpec::Matchers is included via configuration", :include_rspec_matchers => true do
+      it_behaves_like "a normal module with a method that supers"
+    end
+
+    context "when RSpec::Matchers is included in a module that is included via configuration", :include_mod_that_includes_rspec_matchers => true do
+      it_behaves_like "a normal module with a method that supers"
+    end
+  end
+end
+
diff --git a/rspec-core/spec/rspec/core/ruby_project_spec.rb b/rspec-core/spec/rspec/core/ruby_project_spec.rb
new file mode 100644
index 0000000..985a721
--- /dev/null
+++ b/rspec-core/spec/rspec/core/ruby_project_spec.rb
@@ -0,0 +1,51 @@
+module RSpec
+  module Core
+    RSpec.describe RubyProject do
+
+      describe "#determine_root" do
+
+        context "with ancestor containing spec directory" do
+          it "returns ancestor containing the spec directory" do
+            allow(RubyProject).to receive(:ascend_until).and_return('foodir')
+            expect(RubyProject.determine_root).to eq("foodir")
+          end
+        end
+
+        context "without ancestor containing spec directory" do
+          it "returns current working directory" do
+            allow(RubyProject).to receive(:find_first_parent_containing).and_return(nil)
+            expect(RubyProject.determine_root).to eq(".")
+          end
+        end
+
+      end
+
+      describe "#ascend_until" do
+        subject { RubyProject }
+
+        def expect_ascend(source_path, *yielded_paths)
+          expect { |probe|
+            allow(File).to receive(:expand_path).with('.') { source_path }
+            subject.ascend_until(&probe)
+          }.to yield_successive_args(*yielded_paths)
+        end
+
+        it "works with a normal path" do
+          expect_ascend("/var//ponies/", "/var/ponies", "/var", "/")
+        end
+
+        it "works with a path with a trailing slash" do
+          expect_ascend("/var//ponies/", "/var/ponies", "/var", "/")
+        end
+
+        it "works with a path with double slashes" do
+          expect_ascend("/var//ponies/", "/var/ponies", "/var", "/")
+        end
+
+        it "works with a path with escaped slashes" do
+          expect_ascend("/var\\/ponies/", "/var\\/ponies", "/")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/runner_spec.rb b/rspec-core/spec/rspec/core/runner_spec.rb
new file mode 100644
index 0000000..82c917c
--- /dev/null
+++ b/rspec-core/spec/rspec/core/runner_spec.rb
@@ -0,0 +1,273 @@
+require 'rspec/core/drb'
+require 'support/runner_support'
+
+module RSpec::Core
+  RSpec.describe Runner do
+    describe 'invocation' do
+      before do
+        # Simulate invoking the suite like exe/rspec does.
+        allow(RSpec::Core::Runner).to receive(:run)
+        RSpec::Core::Runner.invoke
+      end
+
+      it 'does not autorun after having been invoked' do
+        expect(RSpec::Core::Runner).not_to receive(:at_exit)
+        RSpec::Core::Runner.autorun
+      end
+
+      it 'prints a warning when autorun is attempted' do
+        expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
+        RSpec::Core::Runner.autorun
+      end
+    end
+
+    describe 'at_exit' do
+      it 'sets an at_exit hook if none is already set' do
+        allow(RSpec::Core::Runner).to receive(:autorun_disabled?).and_return(false)
+        allow(RSpec::Core::Runner).to receive(:installed_at_exit?).and_return(false)
+        allow(RSpec::Core::Runner).to receive(:running_in_drb?).and_return(false)
+        allow(RSpec::Core::Runner).to receive(:invoke)
+        expect(RSpec::Core::Runner).to receive(:at_exit)
+        RSpec::Core::Runner.autorun
+      end
+
+      it 'does not set the at_exit hook if it is already set' do
+        allow(RSpec::Core::Runner).to receive(:autorun_disabled?).and_return(false)
+        allow(RSpec::Core::Runner).to receive(:installed_at_exit?).and_return(true)
+        allow(RSpec::Core::Runner).to receive(:running_in_drb?).and_return(false)
+        expect(RSpec::Core::Runner).to receive(:at_exit).never
+        RSpec::Core::Runner.autorun
+      end
+    end
+
+    # This is intermittently slow because this method calls out to the network
+    # interface.
+    describe ".running_in_drb?", :slow do
+      it "returns true if drb server is started with 127.0.0.1" do
+        allow(::DRb).to receive(:current_server).and_return(double(:uri => "druby://127.0.0.1:0000/"))
+
+        expect(RSpec::Core::Runner.running_in_drb?).to be_truthy
+      end
+
+      it "returns true if drb server is started with localhost" do
+        allow(::DRb).to receive(:current_server).and_return(double(:uri => "druby://localhost:0000/"))
+
+        expect(RSpec::Core::Runner.running_in_drb?).to be_truthy
+      end
+
+      it "returns true if drb server is started with another local ip address" do
+        allow(::DRb).to receive(:current_server).and_return(double(:uri => "druby://192.168.0.1:0000/"))
+        allow(::IPSocket).to receive(:getaddress).and_return("192.168.0.1")
+
+        expect(RSpec::Core::Runner.running_in_drb?).to be_truthy
+      end
+
+      it "returns false if no drb server is running" do
+        allow(::DRb).to receive(:current_server).and_raise(::DRb::DRbServerNotFound)
+
+        expect(RSpec::Core::Runner.running_in_drb?).to be_falsey
+      end
+    end
+
+    describe ".invoke" do
+      let(:runner) { RSpec::Core::Runner }
+
+      it "runs the specs via #run" do
+        allow(runner).to receive(:exit)
+        expect(runner).to receive(:run)
+        runner.invoke
+      end
+
+      it "doesn't exit on success" do
+        allow(runner).to receive(:run) { 0 }
+        expect(runner).to_not receive(:exit)
+        runner.invoke
+      end
+
+      it "exits with #run's status on failure" do
+        allow(runner).to receive(:run) { 123 }
+        expect(runner).to receive(:exit).with(123)
+        runner.invoke
+      end
+    end
+
+    describe ".run" do
+      let(:err) { StringIO.new }
+      let(:out) { StringIO.new }
+
+      context "with --drb or -X" do
+        before(:each) do
+          @options = RSpec::Core::ConfigurationOptions.new(%w[--drb --drb-port 8181 --color])
+          allow(RSpec::Core::ConfigurationOptions).to receive(:new) { @options }
+        end
+
+        def run_specs
+          RSpec::Core::Runner.run(%w[ --drb ], err, out)
+        end
+
+        context 'and a DRb server is running' do
+          it "builds a DRbRunner and runs the specs" do
+            drb_proxy = double(RSpec::Core::DRbRunner, :run => true)
+            expect(drb_proxy).to receive(:run).with(err, out)
+
+            expect(RSpec::Core::DRbRunner).to receive(:new).and_return(drb_proxy)
+
+            run_specs
+          end
+        end
+
+        context 'and a DRb server is not running' do
+          before(:each) do
+            expect(RSpec::Core::DRbRunner).to receive(:new).and_raise(DRb::DRbConnError)
+          end
+
+          it "outputs a message" do
+            allow(RSpec.configuration).to receive(:files_to_run) { [] }
+            expect(err).to receive(:puts).with(
+              "No DRb server is running. Running in local process instead ..."
+            )
+            run_specs
+          end
+
+          it "builds a runner instance and runs the specs" do
+            process_proxy = double(RSpec::Core::Runner, :run => 0)
+            expect(process_proxy).to receive(:run).with(err, out)
+
+            expect(RSpec::Core::Runner).to receive(:new).and_return(process_proxy)
+
+            run_specs
+          end
+        end
+      end
+    end
+
+    context "when run" do
+      include_context "Runner support"
+
+      before do
+        allow(config.hooks).to receive(:run)
+      end
+
+      it "configures streams before command line options" do
+        allow(RSpec).to receive(:deprecate)  # remove this and should_receive when ordered
+        stdout = StringIO.new
+        allow(config).to receive(:load_spec_files)
+        allow(config).to receive(:reporter).and_return(double.as_null_object)
+        config.output_stream = $stdout
+
+        # this is necessary to ensure that color works correctly on windows
+        expect(config).to receive(:error_stream=).ordered
+        expect(config).to receive(:output_stream=).ordered
+        expect(config).to receive(:force).at_least(:once).ordered
+
+        runner = build_runner
+        runner.setup err, stdout
+      end
+
+      it "assigns submitted ConfigurationOptions to @options" do
+        config_options = ConfigurationOptions.new(%w[--color])
+        runner         = Runner.new(config_options)
+        expect(runner.instance_exec { @options }).to be(config_options)
+      end
+
+      describe "#run" do
+        it 'supports a test-queue like subclass that can perform setup once and run different sets of example groups multiple times' do
+          order = []
+
+          RSpec.describe("group 1") do
+            before { order << :group_1 }
+            example("passing") { expect(1).to eq(1) }
+          end
+
+          RSpec.describe("group 2") do
+            before { order << :group_2 }
+            example("failed") { expect(1).to eq(2) }
+          end
+
+          subclass = Class.new(Runner) do
+            define_method :run_specs do |example_groups|
+              set_1, set_2 = example_groups.partition { |g| g.description.include?('1') }
+              order << :start_set_1
+              super(set_1)
+              order << :start_set_2
+              super(set_2)
+            end
+          end
+
+          expect(config).to receive(:load_spec_files).once
+          subclass.new(ConfigurationOptions.new([]), config, world).run(err, out)
+          expect(order).to eq([:start_set_1, :group_1, :start_set_2, :group_2])
+        end
+
+        it 'reports the expected example count accurately, even when subclasses filter example groups' do
+          RSpec.describe("group 1") do
+            example("1") { }
+
+            context "nested" do
+              4.times { example { } }
+            end
+          end
+
+          RSpec.describe("group 2") do
+            example("2") { }
+            example("3") { }
+
+            context "nested" do
+              4.times { example { } }
+            end
+          end
+
+          subclass = Class.new(Runner) do
+            define_method :run_specs do |example_groups|
+              super(example_groups.select { |g| g.description == 'group 2' })
+            end
+          end
+
+          my_formatter = instance_double(Formatters::BaseFormatter).as_null_object
+          config.output_stream = out
+          config.deprecation_stream = err
+          config.reporter.register_listener(my_formatter, :start)
+
+          allow(config).to receive(:load_spec_files)
+          subclass.new(ConfigurationOptions.new([]), config, world).run(err, out)
+
+          expect(my_formatter).to have_received(:start) do |notification|
+            expect(notification.count).to eq(6)
+          end
+        end
+
+        context "running files" do
+          include_context "spec files"
+
+          it "returns 0 if spec passes" do
+            runner = build_runner passing_spec_filename
+            expect(runner.run(err, out)).to eq 0
+          end
+
+          it "returns 1 if spec fails" do
+            runner = build_runner failing_spec_filename
+            expect(runner.run(err, out)).to eq 1
+          end
+
+          it "returns 2 if spec fails and --failure-exit-code is 2" do
+            runner = build_runner failing_spec_filename, "--failure-exit-code", "2"
+            expect(runner.run(err, out)).to eq 2
+          end
+        end
+      end
+
+      describe "#run with custom output" do
+        before { allow(config).to receive_messages :files_to_run => [] }
+
+        let(:output_file) { File.new("#{Dir.tmpdir}/runner_spec_output.txt", 'w') }
+
+        it "doesn't override output_stream" do
+          config.output_stream = output_file
+          runner = build_runner
+          runner.run err, nil
+          expect(runner.instance_exec { @configuration.output_stream }).to eq output_file
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/shared_context_spec.rb b/rspec-core/spec/rspec/core/shared_context_spec.rb
new file mode 100644
index 0000000..2fb1cc9
--- /dev/null
+++ b/rspec-core/spec/rspec/core/shared_context_spec.rb
@@ -0,0 +1,100 @@
+RSpec.describe RSpec::SharedContext do
+  it "is accessible as RSpec::Core::SharedContext" do
+    RSpec::Core::SharedContext
+  end
+
+  it "is accessible as RSpec::SharedContext" do
+    RSpec::SharedContext
+  end
+
+  it "supports before and after hooks" do
+    before_all_hook = false
+    before_each_hook = false
+    after_each_hook = false
+    after_all_hook = false
+    shared = Module.new do
+      extend RSpec::SharedContext
+      before(:all) { before_all_hook = true }
+      before(:each) { before_each_hook = true }
+      after(:each)  { after_each_hook = true }
+      after(:all)  { after_all_hook = true }
+    end
+    group = RSpec.describe do
+      include shared
+      example { }
+    end
+
+    group.run
+
+    expect(before_all_hook).to be_truthy
+    expect(before_each_hook).to be_truthy
+    expect(after_each_hook).to be_truthy
+    expect(after_all_hook).to be_truthy
+  end
+
+  include RSpec::Core::SharedExampleGroup::TopLevelDSL
+
+  it "runs the before each hooks in configuration before those of the shared context" do
+    ordered_hooks = []
+    RSpec.configure do |c|
+      c.before(:each) { ordered_hooks << "config" }
+    end
+
+    RSpec.shared_context("before each stuff", :example => :before_each_hook_order) do
+      before(:each) { ordered_hooks << "shared_context"}
+    end
+
+    group = RSpec.describe "description", :example => :before_each_hook_order do
+      before(:each) { ordered_hooks << "example_group" }
+      example {}
+    end
+
+    group.run
+
+    expect(ordered_hooks).to be == ["config", "shared_context", "example_group"]
+  end
+
+  it "supports let" do
+    shared = Module.new do
+      extend RSpec::SharedContext
+      let(:foo) { 'foo' }
+    end
+    group = RSpec.describe do
+      include shared
+    end
+
+    expect(group.new.foo).to eq('foo')
+  end
+
+  it 'supports explicit subjects' do
+    shared = Module.new do
+      extend RSpec::SharedContext
+      subject { 17 }
+    end
+
+    group = RSpec.describe do
+      include shared
+    end
+
+    expect(group.new.subject).to eq(17)
+  end
+
+  %w[describe context].each do |method_name|
+    it "supports nested example groups using #{method_name}" do
+      shared = Module.new do
+        extend RSpec::SharedContext
+        send(method_name, "nested using describe") do
+          example {}
+        end
+      end
+      group = RSpec.describe do
+        include shared
+      end
+
+      group.run
+
+      expect(group.children.length).to eq(1)
+      expect(group.children.first.examples.length).to eq(1)
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/shared_example_group_spec.rb b/rspec-core/spec/rspec/core/shared_example_group_spec.rb
new file mode 100644
index 0000000..65b82b8
--- /dev/null
+++ b/rspec-core/spec/rspec/core/shared_example_group_spec.rb
@@ -0,0 +1,353 @@
+require 'rspec/support/spec/in_sub_process'
+
+module RandomTopLevelModule
+  def self.setup!
+    RSpec.shared_examples_for("top level in module") {}
+  end
+end
+
+module RSpec
+  module Core
+    RSpec.describe SharedExampleGroup do
+      include RSpec::Support::InSubProcess
+      let(:registry) { RSpec.world.shared_example_group_registry }
+
+      ExampleModule = Module.new
+      ExampleClass  = Class.new
+
+      it 'does not add a bunch of private methods to Module' do
+        seg_methods = RSpec::Core::SharedExampleGroup.private_instance_methods
+        expect(Module.private_methods & seg_methods).to eq([])
+      end
+
+      before do
+        # this is a work around as SharedExampleGroup is not world safe
+        RandomTopLevelModule.setup!
+      end
+
+      RSpec::Matchers.define :have_example_descriptions do |*descriptions|
+        match do |example_group|
+          example_group.examples.map(&:description) == descriptions
+        end
+
+        failure_message do |example_group|
+          actual = example_group.examples.map(&:description)
+          "expected #{example_group.name} to have descriptions: #{descriptions.inspect} but had #{actual.inspect}"
+        end
+      end
+
+      %w[shared_examples shared_examples_for shared_context].each do |shared_method_name|
+        describe shared_method_name do
+          let(:group) { RSpec.describe('example group') }
+
+          define_method :define_shared_group do |*args, &block|
+            group.send(shared_method_name, *args, &block)
+          end
+
+          it "is exposed to the global namespace when expose_dsl_globally is enabled" do
+            in_sub_process do
+              RSpec.configuration.expose_dsl_globally = true
+              expect(Kernel).to respond_to(shared_method_name)
+            end
+          end
+
+          it "is not exposed to the global namespace when monkey patching is disabled" do
+            RSpec.configuration.expose_dsl_globally = false
+            expect(Kernel).to_not respond_to(shared_method_name)
+          end
+
+          it "displays a warning when adding a second shared example group with the same name" do
+            group.send(shared_method_name, 'some shared group') {}
+            original_declaration = [__FILE__, __LINE__ - 1].join(':')
+
+            warning = nil
+            allow(::Kernel).to receive(:warn) { |msg| warning = msg }
+
+            group.send(shared_method_name, 'some shared group') {}
+            second_declaration = [__FILE__, __LINE__ - 1].join(':')
+            expect(warning).to include('some shared group', original_declaration, second_declaration)
+            expect(warning).to_not include 'Called from'
+          end
+
+          it 'works with top level defined examples in modules' do
+            expect(RSpec::configuration.reporter).to_not receive(:deprecation)
+            RSpec.describe('example group') { include_context 'top level in module' }
+          end
+
+          it 'generates a named (rather than anonymous) module' do
+            define_shared_group("shared behaviors", :include_it) { }
+            example_group = RSpec.describe("Group", :include_it) { }
+
+            anonymous_module_regex = /#<Module:0x[0-9a-f]+>/
+            expect(Module.new.inspect).to match(anonymous_module_regex)
+
+            include_a_named_rather_than_anonymous_module = (
+              include(a_string_including(
+                "#<RSpec::Core::SharedExampleGroupModule", "shared behaviors"
+              )).and exclude(a_string_matching(anonymous_module_regex))
+            )
+
+            expect(example_group.ancestors.map(&:inspect)).to include_a_named_rather_than_anonymous_module
+            expect(example_group.ancestors.map(&:to_s)).to include_a_named_rather_than_anonymous_module
+          end
+
+          ["name", :name, ExampleModule, ExampleClass].each do |object|
+            type = object.class.name.downcase
+            context "given a #{type}" do
+              it "captures the given #{type} and block in the collection of shared example groups" do
+                implementation = lambda { }
+                define_shared_group(object, &implementation)
+                expect(registry.find([group], object)).to eq implementation
+              end
+            end
+          end
+
+          context "given a hash" do
+            it "includes itself in matching example groups" do
+              implementation = Proc.new { def self.bar; 'bar'; end }
+              define_shared_group(:foo => :bar, &implementation)
+
+              matching_group = RSpec.describe "Group", :foo => :bar
+              non_matching_group = RSpec.describe "Group"
+
+              expect(matching_group.bar).to eq("bar")
+              expect(non_matching_group).not_to respond_to(:bar)
+            end
+          end
+
+          context "given a string and a hash" do
+            it "captures the given string and block in the World's collection of shared example groups" do
+              implementation = lambda { }
+              define_shared_group("name", :foo => :bar, &implementation)
+              expect(registry.find([group], "name")).to eq implementation
+            end
+
+            it "delegates include on configuration" do
+              implementation = Proc.new { def self.bar; 'bar'; end }
+              define_shared_group("name", :foo => :bar, &implementation)
+
+              matching_group = RSpec.describe "Group", :foo => :bar
+              non_matching_group = RSpec.describe "Group"
+
+              expect(matching_group.bar).to eq("bar")
+              expect(non_matching_group).not_to respond_to(:bar)
+            end
+
+            describe "hooks for individual examples that have matching metadata" do
+              before do
+                skip "These specs pass in 2.0 mode on JRuby 1.7.8 but fail on " \
+                     "1.7.15 when the entire spec suite runs. They pass on " \
+                     "1.7.15 when this one spec file is run or if we filter to " \
+                     "just them. Given that 2.0 support on JRuby 1.7 is " \
+                     "experimental, we're just skipping these specs."
+              end if RUBY_VERSION == "2.0.0" && RSpec::Support::Ruby.jruby?
+
+              it 'runs them' do
+                sequence = []
+
+                define_shared_group("name", :include_it) do
+                  before(:context) { sequence << :before_context }
+                  after(:context)  { sequence << :after_context }
+
+                  before(:example) { sequence << :before_example }
+                  after(:example)  { sequence << :after_example  }
+
+                  around(:example) do |ex|
+                    sequence << :around_example_before
+                    ex.run
+                    sequence << :around_example_after
+                  end
+                end
+
+                RSpec.describe "group" do
+                  example("ex1") { sequence << :unmatched_example_1 }
+                  example("ex2", :include_it) { sequence << :matched_example }
+                  example("ex3") { sequence << :unmatched_example_2 }
+                end.run
+
+                expect(sequence).to eq([
+                  :unmatched_example_1,
+                  :before_context,
+                  :around_example_before,
+                  :before_example,
+                  :matched_example,
+                  :after_example,
+                  :around_example_after,
+                  :after_context,
+                  :unmatched_example_2
+                ])
+              end
+
+              it 'runs the `after(:context)` hooks even if the `before(:context)` hook raises an error' do
+                sequence = []
+
+                define_shared_group("name", :include_it) do
+                  before(:context) do
+                    sequence << :before_context
+                    raise "boom"
+                  end
+                  after(:context) { sequence << :after_context }
+                end
+
+                RSpec.describe "group" do
+                  example("ex", :include_it) { sequence << :example }
+                end.run
+
+                expect(sequence).to eq([ :before_context, :after_context ])
+              end
+            end
+          end
+
+          context "when called at the top level" do
+            before do
+              RSpec.__send__(shared_method_name, "shared context") do
+                example "shared spec"
+              end
+            end
+
+            it 'is available for inclusion from a top level group' do
+              group = RSpec.describe "group" do
+                include_examples "shared context"
+              end
+
+              expect(group).to have_example_descriptions("shared spec")
+            end
+
+            it 'is available for inclusion from a nested example group' do
+              group = nil
+
+              RSpec.describe "parent" do
+                context "child" do
+                  group = context("grand child") { include_examples "shared context" }
+                end
+              end
+
+              expect(group).to have_example_descriptions("shared spec")
+            end
+
+            it 'is trumped by a shared group with the same name that is defined in the including context' do
+              group = RSpec.describe "parent" do
+                __send__ shared_method_name, "shared context" do
+                  example "a different spec"
+                end
+
+                include_examples "shared context"
+              end
+
+              expect(group).to have_example_descriptions("a different spec")
+            end
+
+            it 'is trumped by a shared group with the same name that is defined in a parent group' do
+              group = nil
+
+              RSpec.describe "parent" do
+                __send__ shared_method_name, "shared context" do
+                  example "a different spec"
+                end
+
+                group = context("nested") { include_examples "shared context" }
+              end
+
+              expect(group).to have_example_descriptions("a different spec")
+            end
+          end
+
+          context "when called from within an example group" do
+            define_method :in_group_with_shared_group_def do |&block|
+              RSpec.describe "an example group" do
+                __send__ shared_method_name, "shared context" do
+                  example "shared spec"
+                end
+
+                module_exec(&block)
+              end
+            end
+
+            it 'is available for inclusion within that group' do
+              group = in_group_with_shared_group_def do
+                include_examples "shared context"
+              end
+
+              expect(group).to have_example_descriptions("shared spec")
+            end
+
+            it 'is available for inclusion in a child group' do
+              group = nil
+
+              in_group_with_shared_group_def do
+                group = context("nested") { include_examples "shared context" }
+              end
+
+              expect(group).to have_example_descriptions("shared spec")
+            end
+
+            it 'is not available for inclusion in a different top level group' do
+              in_group_with_shared_group_def { }
+
+              expect {
+                RSpec.describe "another top level group" do
+                  include_examples "shared context"
+                end
+              }.to raise_error(/Could not find/)
+            end
+
+            it 'is not available for inclusion in a nested group of a different top level group' do
+              in_group_with_shared_group_def { }
+
+              expect {
+                RSpec.describe "another top level group" do
+                  context("nested") { include_examples "shared context" }
+                end
+              }.to raise_error(/Could not find/)
+            end
+
+            it 'trumps a shared group with the same name defined at the top level' do
+              RSpec.__send__(shared_method_name, "shared context") do
+                example "a different spec"
+              end
+
+              group = in_group_with_shared_group_def do
+                include_examples "shared context"
+              end
+
+              expect(group).to have_example_descriptions("shared spec")
+            end
+
+            it 'is trumped by a shared group with the same name that is defined in the including context' do
+              group = nil
+
+              in_group_with_shared_group_def do
+                group = context "child" do
+                  __send__ shared_method_name, "shared context" do
+                    example "a different spec"
+                  end
+
+                  include_examples "shared context"
+                end
+              end
+
+              expect(group).to have_example_descriptions("a different spec")
+            end
+
+            it 'is trumped by a shared group with the same name that is defined in nearer parent group' do
+              group = nil
+
+              in_group_with_shared_group_def do
+                context "child" do
+                  __send__ shared_method_name, "shared context" do
+                    example "a different spec"
+                  end
+
+                  group = context("grandchild") { include_examples "shared context" }
+                end
+              end
+
+              expect(group).to have_example_descriptions("a different spec")
+            end
+          end
+        end
+      end
+    end
+  end
+end
+
diff --git a/rspec-core/spec/rspec/core/suite_hooks_spec.rb b/rspec-core/spec/rspec/core/suite_hooks_spec.rb
new file mode 100644
index 0000000..2af89f8
--- /dev/null
+++ b/rspec-core/spec/rspec/core/suite_hooks_spec.rb
@@ -0,0 +1,112 @@
+require "support/runner_support"
+
+module RSpec::Core
+  RSpec.describe "Configuration :suite hooks" do
+    [:before, :after, :prepend_before, :append_before, :prepend_after, :append_after].each do |registration_method|
+      type = registration_method.to_s.split('_').last
+
+      describe "a `:suite` hook registered with `#{registration_method}" do
+        it 'is skipped when in dry run mode' do
+          RSpec.configuration.dry_run = true
+
+          expect { |b|
+            RSpec.configuration.__send__(registration_method, :suite, &b)
+            RSpec.configuration.with_suite_hooks { }
+          }.not_to yield_control
+        end
+
+        it 'allows errors in the hook to propagate to the user' do
+          RSpec.configuration.__send__(registration_method, :suite) { 1 / 0 }
+
+          expect {
+            RSpec.configuration.with_suite_hooks { }
+          }.to raise_error(ZeroDivisionError)
+        end
+
+        context "registered on an example group" do
+          it "is ignored with a clear warning" do
+            sequence = []
+
+            expect {
+              RSpec.describe "Group" do
+                __send__(registration_method, :suite) { sequence << :suite_hook }
+                example { sequence << :example }
+              end.run
+            }.to change { sequence }.to([:example]).
+              and output(a_string_including("#{type}(:suite)")).to_stderr
+          end
+        end
+
+        context "registered with metadata" do
+          it "explicitly warns that the metadata is ignored" do
+            expect {
+              RSpec.configure do |c|
+                c.__send__(registration_method, :suite, :some => :metadata)
+              end
+            }.to output(a_string_including(":suite", "metadata")).to_stderr
+          end
+        end
+      end
+    end
+
+    it 'always runs `after(:suite)` hooks even in the face of errors' do
+      expect { |b|
+        RSpec.configuration.after(:suite, &b)
+        RSpec.configuration.with_suite_hooks { raise "boom" }
+      }.to raise_error("boom").and yield_control
+    end
+
+    describe "the runner" do
+      include_context "Runner support"
+
+      def define_and_run_example_group(&block)
+        example_group = class_double(ExampleGroup, :descendants => [])
+
+        allow(example_group).to receive(:run, &block)
+        allow(world).to receive_messages(:ordered_example_groups => [example_group])
+        allow(config).to receive :load_spec_files
+
+        runner = build_runner
+        runner.run err, out
+      end
+
+      it "still runs :suite hooks with metadata even though the metadata is ignored" do
+        sequence = []
+        allow(RSpec).to receive(:warn_with)
+
+        config.before(:suite, :foo)  { sequence << :before_suite   }
+        config.after(:suite, :foo)   { sequence << :after_suite    }
+        define_and_run_example_group { sequence << :example_groups }
+
+        expect(sequence).to eq([ :before_suite, :example_groups, :after_suite ])
+      end
+
+      it "runs :suite hooks before and after example groups in the correct order" do
+        sequence = []
+
+        config.before(:suite)         { sequence << :before_suite_2 }
+        config.before(:suite)         { sequence << :before_suite_3 }
+        config.append_before(:suite)  { sequence << :before_suite_4 }
+        config.prepend_before(:suite) { sequence << :before_suite_1 }
+        config.after(:suite)          { sequence << :after_suite_3  }
+        config.after(:suite)          { sequence << :after_suite_2  }
+        config.prepend_after(:suite)  { sequence << :after_suite_1  }
+        config.append_after(:suite)   { sequence << :after_suite_4  }
+
+        define_and_run_example_group { sequence << :example_groups }
+
+        expect(sequence).to eq([
+          :before_suite_1,
+          :before_suite_2,
+          :before_suite_3,
+          :before_suite_4,
+          :example_groups,
+          :after_suite_1,
+          :after_suite_2,
+          :after_suite_3,
+          :after_suite_4
+        ])
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/warnings_spec.rb b/rspec-core/spec/rspec/core/warnings_spec.rb
new file mode 100644
index 0000000..5b45053
--- /dev/null
+++ b/rspec-core/spec/rspec/core/warnings_spec.rb
@@ -0,0 +1,70 @@
+RSpec.describe "rspec warnings and deprecations" do
+
+  describe "#deprecate" do
+    it "passes the hash to the reporter" do
+      expect(RSpec.configuration.reporter).to receive(:deprecation).with(hash_including :deprecated => "deprecated_method", :replacement => "replacement")
+      RSpec.deprecate("deprecated_method", :replacement => "replacement")
+    end
+
+    it "adds the call site" do
+      expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
+      RSpec.deprecate("deprecated_method")
+    end
+
+    it "doesn't override a passed call site" do
+      expect_deprecation_with_call_site("some_file.rb", 17)
+      RSpec.deprecate("deprecated_method", :call_site => "/some_file.rb:17")
+    end
+  end
+
+  describe "#warn_deprecation" do
+    it "puts message in a hash" do
+      expect(RSpec.configuration.reporter).to receive(:deprecation).with(hash_including :message => "this is the message")
+      RSpec.warn_deprecation("this is the message")
+    end
+
+    it "passes along additional options" do
+      expect(RSpec.configuration.reporter).to receive(:deprecation).with(hash_including :type => :tag)
+      RSpec.warn_deprecation("this is the message", :type => :tag)
+    end
+  end
+
+  describe "#warn_with" do
+    context "when :use_spec_location_as_call_site => true is passed" do
+      let(:options) do
+        {
+          :use_spec_location_as_call_site => true,
+          :call_site                      => nil,
+        }
+      end
+
+      it "adds the source location of spec" do
+        line = __LINE__ - 1
+        file_path = RSpec::Core::Metadata.relative_path(__FILE__)
+        expect(Kernel).to receive(:warn).with(/The warning. Warning generated from spec at `#{file_path}:#{line}`./)
+
+        RSpec.warn_with("The warning.", options)
+      end
+
+      it "appends a period to the supplied message if one is not present" do
+        line = __LINE__ - 1
+        file_path = RSpec::Core::Metadata.relative_path(__FILE__)
+        expect(Kernel).to receive(:warn).with(/The warning. Warning generated from spec at `#{file_path}:#{line}`./)
+
+        RSpec.warn_with("The warning", options)
+      end
+
+      context "when there is no current example" do
+        before do
+          allow(RSpec).to receive(:current_example).and_return(nil)
+        end
+
+        it "adds no message about the spec location" do
+          expect(Kernel).to receive(:warn).with(/The warning\.$/)
+
+          RSpec.warn_with("The warning.", options)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core/world_spec.rb b/rspec-core/spec/rspec/core/world_spec.rb
new file mode 100644
index 0000000..a837a13
--- /dev/null
+++ b/rspec-core/spec/rspec/core/world_spec.rb
@@ -0,0 +1,140 @@
+class Bar; end
+class Foo; end
+
+module RSpec::Core
+
+  RSpec.describe RSpec::Core::World do
+    let(:configuration) { RSpec::Core::Configuration.new }
+    let(:world) { RSpec::Core::World.new(configuration) }
+
+    describe '#reset' do
+      it 'clears #example_groups' do
+        world.example_groups << :example_group
+        world.reset
+        expect(world.example_groups).to be_empty
+      end
+    end
+
+    describe "#example_groups" do
+      it "contains all registered example groups" do
+        example_group = RSpec.describe("group") {}
+        world.register(example_group)
+        expect(world.example_groups).to include(example_group)
+      end
+    end
+
+    describe "#preceding_declaration_line (again)" do
+      let(:group) do
+        RSpec.describe("group") do
+
+          example("example") {}
+
+        end
+      end
+
+      let(:second_group) do
+        RSpec.describe("second_group") do
+
+          example("second_example") {}
+
+        end
+      end
+
+      let(:group_declaration_line) { group.metadata[:line_number] }
+      let(:example_declaration_line) { group_declaration_line + 2 }
+
+      context "with one example" do
+        before { world.register(group) }
+
+        it "returns nil if no example or group precedes the line" do
+          expect(world.preceding_declaration_line(group_declaration_line - 1)).to be_nil
+        end
+
+        it "returns the argument line number if a group starts on that line" do
+          expect(world.preceding_declaration_line(group_declaration_line)).to eq(group_declaration_line)
+        end
+
+        it "returns the argument line number if an example starts on that line" do
+          expect(world.preceding_declaration_line(example_declaration_line)).to eq(example_declaration_line)
+        end
+
+        it "returns line number of a group that immediately precedes the argument line" do
+          expect(world.preceding_declaration_line(group_declaration_line + 1)).to eq(group_declaration_line)
+        end
+
+        it "returns line number of an example that immediately precedes the argument line" do
+          expect(world.preceding_declaration_line(example_declaration_line + 1)).to eq(example_declaration_line)
+        end
+      end
+
+      context "with two exaples and the second example is registre first" do
+        let(:second_group_declaration_line) { second_group.metadata[:line_number] }
+
+        before do
+          world.register(second_group)
+          world.register(group)
+        end
+
+        it 'return line number of group if a group start on that line' do
+          expect(world.preceding_declaration_line(second_group_declaration_line)).to eq(second_group_declaration_line)
+        end
+      end
+    end
+
+    describe "#announce_filters" do
+      let(:reporter) { double('reporter').as_null_object }
+      before { allow(world).to receive(:reporter) { reporter } }
+
+      context "with no examples" do
+        before { allow(world).to receive(:example_count) { 0 } }
+
+        context "with no filters" do
+          it "announces" do
+            expect(reporter).to receive(:message).
+              with("No examples found.")
+            world.announce_filters
+          end
+        end
+
+        context "with an inclusion filter" do
+          it "announces" do
+            configuration.filter_run_including :foo => 'bar'
+            expect(reporter).to receive(:message).
+              with(/All examples were filtered out/)
+            world.announce_filters
+          end
+        end
+
+        context "with an inclusion filter and run_all_when_everything_filtered" do
+          it "announces" do
+            allow(configuration).to receive(:run_all_when_everything_filtered?) { true }
+            configuration.filter_run_including :foo => 'bar'
+            expect(reporter).to receive(:message).
+              with(/All examples were filtered out/)
+            world.announce_filters
+          end
+        end
+
+        context "with an exclusion filter" do
+          it "announces" do
+            configuration.filter_run_excluding :foo => 'bar'
+            expect(reporter).to receive(:message).
+              with(/All examples were filtered out/)
+            world.announce_filters
+          end
+        end
+      end
+
+      context "with examples" do
+        before { allow(world).to receive(:example_count) { 1 } }
+
+        context "with no filters" do
+          it "does not announce" do
+            expect(reporter).not_to receive(:message)
+            world.announce_filters
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/rspec/core_spec.rb b/rspec-core/spec/rspec/core_spec.rb
new file mode 100644
index 0000000..a367e92
--- /dev/null
+++ b/rspec-core/spec/rspec/core_spec.rb
@@ -0,0 +1,208 @@
+require 'rspec/support/spec/prevent_load_time_warnings'
+
+RSpec.describe RSpec do
+  fake_minitest = File.expand_path('../../support/fake_minitest', __FILE__)
+  it_behaves_like 'a library that issues no warnings when loaded', 'rspec-core',
+    # Loading minitest issues warnings, so we put our fake minitest on the load
+    # path to prevent the real minitest from being loaded.
+    "$LOAD_PATH.unshift '#{fake_minitest}'", 'require "rspec/core"', 'RSpec::Core::Runner.disable_autorun!' do
+
+    pending_when = {
+      '1.9.2' => { :description => "issues no warnings when loaded" },
+      '1.8.7' => { :description => "issues no warnings when the spec files are loaded" },
+      '2.0.0' => { }
+    }
+
+    if RUBY_VERSION == '1.9.2' || RUBY_VERSION == '1.8.7'
+      before(:example, pending_when.fetch(RUBY_VERSION)) do
+        pending "Not working on #{RUBY_DESCRIPTION}"
+      end
+    end
+    if (RUBY_PLATFORM == 'java' && RUBY_VERSION == '2.0.0')
+      before(:example, pending_when.fetch(RUBY_VERSION)) do
+        skip "Not reliably working on #{RUBY_DESCRIPTION}"
+      end
+    end
+  end
+
+  describe ".configuration" do
+    it "returns the same object every time" do
+      expect(RSpec.configuration).to equal(RSpec.configuration)
+    end
+  end
+
+  describe ".configuration=" do
+    it "sets the configuration object" do
+      configuration = RSpec::Core::Configuration.new
+
+      RSpec.configuration = configuration
+
+      expect(RSpec.configuration).to equal(configuration)
+    end
+  end
+
+  describe ".configure" do
+    it "yields the current configuration" do
+      RSpec.configure do |config|
+        expect(config).to equal(RSpec::configuration)
+      end
+    end
+  end
+
+  describe ".world" do
+    it "returns the same object every time" do
+      expect(RSpec.world).to equal(RSpec.world)
+    end
+  end
+
+  describe ".world=" do
+    it "sets the world object" do
+      world = RSpec::Core::World.new
+
+      RSpec.world = world
+
+      expect(RSpec.world).to equal(world)
+    end
+  end
+
+  describe ".current_example" do
+    it "sets the example being executed" do
+      group = RSpec.describe("an example group")
+      example = group.example("an example")
+
+      RSpec.current_example = example
+      expect(RSpec.current_example).to be(example)
+    end
+  end
+
+  describe ".reset" do
+    it "resets the configuration and world objects" do
+      config_before_reset = RSpec.configuration
+      world_before_reset  = RSpec.world
+
+      RSpec.reset
+
+      expect(RSpec.configuration).not_to equal(config_before_reset)
+      expect(RSpec.world).not_to equal(world_before_reset)
+    end
+  end
+
+  describe ".clear_examples" do
+    let(:listener) { double("listener") }
+    let(:reporter) { RSpec.configuration.reporter }
+
+    before do
+      RSpec.configuration.output_stream = StringIO.new
+      RSpec.configuration.error_stream = StringIO.new
+    end
+
+    it "clears example groups" do
+      RSpec.world.example_groups << :example_group
+
+      RSpec.clear_examples
+
+      expect(RSpec.world.example_groups).to be_empty
+    end
+
+    it "resets start_time" do
+      start_time_before_clear = RSpec.configuration.start_time
+
+      RSpec.clear_examples
+
+      expect(RSpec.configuration.start_time).not_to eq(start_time_before_clear)
+    end
+
+    it "clears examples, failed_examples and pending_examples" do
+      reporter.start(3)
+      pending_ex = failing_ex = nil
+
+      RSpec.describe do
+        pending_ex = pending { fail }
+        failing_ex = example { fail }
+      end.run
+
+      reporter.example_started(failing_ex)
+      reporter.example_failed(failing_ex)
+
+      reporter.example_started(pending_ex)
+      reporter.example_pending(pending_ex)
+      reporter.finish
+
+      reporter.register_listener(listener, :dump_summary)
+
+      expect(listener).to receive(:dump_summary) do |notification|
+        expect(notification.examples).to be_empty
+        expect(notification.failed_examples).to be_empty
+        expect(notification.pending_examples).to be_empty
+      end
+
+      RSpec.clear_examples
+      reporter.start(0)
+      reporter.finish
+    end
+
+    it "restores inclusion rules set by configuration" do
+      file_path = File.expand_path("foo_spec.rb")
+      RSpec.configure do |config|
+        config.filter_run_including(:locations => { file_path => [12] })
+      end
+      allow(RSpec.configuration).to receive(:load).with(file_path)
+      allow(reporter).to receive(:report)
+      RSpec::Core::Runner.run(["foo_spec.rb:14"])
+
+      expect(
+        RSpec.configuration.filter_manager.inclusions[:locations]
+      ).to eq(file_path => [12, 14])
+
+      RSpec.clear_examples
+
+      expect(
+        RSpec.configuration.filter_manager.inclusions[:locations]
+      ).to eq(file_path => [12])
+    end
+
+    it "restores exclusion rules set by configuration" do
+      RSpec.configure { |config| config.filter_run_excluding(:slow => true) }
+      allow(RSpec.configuration).to receive(:load)
+      allow(reporter).to receive(:report)
+      RSpec::Core::Runner.run(["--tag", "~fast"])
+
+      expect(
+        RSpec.configuration.filter_manager.exclusions.rules
+      ).to eq(:slow => true, :fast => true)
+
+      RSpec.clear_examples
+
+      expect(
+        RSpec.configuration.filter_manager.exclusions.rules
+      ).to eq(:slow => true)
+    end
+  end
+
+  describe "::Core.path_to_executable" do
+    it 'returns the absolute location of the exe/rspec file', :failing_on_appveyor do
+      expect(File.exist? RSpec::Core.path_to_executable).to be_truthy
+      expect(File.executable? RSpec::Core.path_to_executable).to be_truthy
+    end
+  end
+
+  include RSpec::Support::ShellOut
+
+  # This is hard to test :(. Best way I could come up with was starting
+  # fresh ruby process w/o this stuff already loaded.
+  it "loads mocks and expectations when the constants are referenced", :slow do
+    code = 'require "rspec"; puts RSpec::Mocks.name; puts RSpec::Expectations.name'
+    out, err, status = run_ruby_with_current_load_path(code)
+
+    expect(err).to eq("")
+    expect(out.split("\n")).to eq(%w[ RSpec::Mocks RSpec::Expectations ])
+    expect(status.exitstatus).to eq(0)
+  end
+
+  it 'correctly raises an error when an invalid const is referenced' do
+    expect {
+      RSpec::NotAConst
+    }.to raise_error(NameError, /RSpec::NotAConst/)
+  end
+end
+
diff --git a/rspec-core/spec/spec_helper.rb b/rspec-core/spec/spec_helper.rb
new file mode 100644
index 0000000..81bc9b3
--- /dev/null
+++ b/rspec-core/spec/spec_helper.rb
@@ -0,0 +1,74 @@
+require 'rubygems' if RUBY_VERSION.to_f < 1.9
+
+require 'rspec/support/spec'
+
+if RUBY_PLATFORM == 'java'
+  # Works around https://jira.codehaus.org/browse/JRUBY-5678
+  require 'fileutils'
+  ENV['TMPDIR'] = File.expand_path('../../tmp', __FILE__)
+  FileUtils.mkdir_p(ENV['TMPDIR'])
+end
+
+$rspec_core_without_stderr_monkey_patch = RSpec::Core::Configuration.new
+
+class RSpec::Core::Configuration
+  def self.new(*args, &block)
+    super.tap do |config|
+      # We detect ruby warnings via $stderr,
+      # so direct our deprecations to $stdout instead.
+      config.deprecation_stream = $stdout
+    end
+  end
+end
+
+Dir['./spec/support/**/*.rb'].map do |file|
+  # Ensure requires are relative to `spec`, which is on the
+  # load path. This helps prevent double requires on 1.8.7.
+  require file.gsub("./spec/support", "support")
+end
+
+module EnvHelpers
+  def with_env_vars(vars)
+    original = ENV.to_hash
+    vars.each { |k, v| ENV[k] = v }
+
+    begin
+      yield
+    ensure
+      ENV.replace(original)
+    end
+  end
+
+  def without_env_vars(*vars)
+    original = ENV.to_hash
+    vars.each { |k| ENV.delete(k) }
+
+    begin
+      yield
+    ensure
+      ENV.replace(original)
+    end
+  end
+end
+
+RSpec.configure do |c|
+  # structural
+  c.alias_it_behaves_like_to 'it_has_behavior'
+  c.include(RSpecHelpers)
+  c.disable_monkey_patching!
+
+  # runtime options
+  c.raise_errors_for_deprecations!
+  c.color = true
+  c.include EnvHelpers
+  c.filter_run_excluding :ruby => lambda {|version|
+    case version.to_s
+    when "!jruby"
+      RUBY_ENGINE == "jruby"
+    when /^> (.*)/
+      !(RUBY_VERSION.to_s > $1)
+    else
+      !(RUBY_VERSION.to_s =~ /^#{version.to_s}/)
+    end
+  }
+end
diff --git a/rspec-core/spec/support/aruba_support.rb b/rspec-core/spec/support/aruba_support.rb
new file mode 100644
index 0000000..333b4a2
--- /dev/null
+++ b/rspec-core/spec/support/aruba_support.rb
@@ -0,0 +1,60 @@
+module ArubaLoader
+  extend RSpec::Support::WithIsolatedStdErr
+  with_isolated_stderr do
+    require 'aruba/api'
+  end
+end
+
+RSpec.shared_context "aruba support" do
+  include Aruba::Api
+  let(:stderr) { StringIO.new }
+  let(:stdout) { StringIO.new }
+
+  attr_reader :last_cmd_stdout, :last_cmd_stderr
+
+  def run_command(cmd)
+    RSpec.configuration.color = true
+
+    temp_stdout = StringIO.new
+    temp_stderr = StringIO.new
+    RSpec::Core::Metadata.instance_variable_set(:@relative_path_regex, nil)
+
+    in_current_dir do
+      RSpec::Core::Runner.run(cmd.split, temp_stderr, temp_stdout)
+    end
+  ensure
+    RSpec.reset
+    RSpec.configuration.color = true
+    RSpec::Core::Metadata.instance_variable_set(:@relative_path_regex, nil)
+
+    # Ensure it gets cached with a proper value -- if we leave it set to nil,
+    # and the next spec operates in a different dir, it could get set to an
+    # invalid value.
+    RSpec::Core::Metadata.relative_path_regex
+
+    @last_cmd_stdout = temp_stdout.string
+    @last_cmd_stderr = temp_stderr.string
+    stdout.write(@last_cmd_stdout)
+    stderr.write(@last_cmd_stderr)
+  end
+
+  def write_file_formatted(file_name, contents)
+    # remove blank line at the start of the string and
+    # strip extra indentation.
+    formatted_contents = unindent(contents.sub(/\A\n/, ""))
+    write_file file_name, formatted_contents
+  end
+
+  # Intended for use with indented heredocs.
+  # taken from Ruby Tapas:
+  # https://rubytapas.dpdcart.com/subscriber/post?id=616#files
+  def unindent(s)
+    s.gsub(/^#{s.scan(/^[ \t]+(?=\S)/).min}/, "")
+  end
+end
+
+RSpec.configure do |c|
+  c.define_derived_metadata(:file_path => %r{spec/integration}) do |meta|
+    meta[:slow] = true
+  end
+end
diff --git a/rspec-core/spec/support/config_options_helper.rb b/rspec-core/spec/support/config_options_helper.rb
new file mode 100644
index 0000000..c30e2a5
--- /dev/null
+++ b/rspec-core/spec/support/config_options_helper.rb
@@ -0,0 +1,13 @@
+module ConfigOptionsHelper
+  extend RSpec::SharedContext
+
+  around(:each) { |e| without_env_vars('SPEC_OPTS', &e) }
+
+  def config_options_object(*args)
+    RSpec::Core::ConfigurationOptions.new(args)
+  end
+
+  def parse_options(*args)
+    config_options_object(*args).options
+  end
+end
diff --git a/rspec-core/spec/support/fake_minitest/minitest.rb b/rspec-core/spec/support/fake_minitest/minitest.rb
new file mode 100644
index 0000000..e69de29
diff --git a/rspec-core/spec/support/fake_minitest/minitest/minitest_assertions.rb b/rspec-core/spec/support/fake_minitest/minitest/minitest_assertions.rb
new file mode 100644
index 0000000..bcb5866
--- /dev/null
+++ b/rspec-core/spec/support/fake_minitest/minitest/minitest_assertions.rb
@@ -0,0 +1,4 @@
+module Minitest
+  module Assertions
+  end
+end
diff --git a/rspec-core/spec/support/fake_minitest/test/unit/assertions.rb b/rspec-core/spec/support/fake_minitest/test/unit/assertions.rb
new file mode 100644
index 0000000..600a3f4
--- /dev/null
+++ b/rspec-core/spec/support/fake_minitest/test/unit/assertions.rb
@@ -0,0 +1,6 @@
+module Test
+  module Unit
+    module Assertions
+    end
+  end
+end
diff --git a/rspec-core/spec/support/formatter_support.rb b/rspec-core/spec/support/formatter_support.rb
new file mode 100644
index 0000000..0d146ce
--- /dev/null
+++ b/rspec-core/spec/support/formatter_support.rb
@@ -0,0 +1,282 @@
+module FormatterSupport
+  def run_example_specs_with_formatter(formatter_option)
+    options = RSpec::Core::ConfigurationOptions.new(%W[spec/rspec/core/resources/formatter_specs.rb --format #{formatter_option} --order defined])
+
+    err, out = StringIO.new, StringIO.new
+    err.set_encoding("utf-8") if err.respond_to?(:set_encoding)
+
+    runner = RSpec::Core::Runner.new(options)
+    configuration = runner.instance_variable_get("@configuration")
+    configuration.backtrace_formatter.exclusion_patterns << /rspec_with_simplecov/
+    configuration.backtrace_formatter.inclusion_patterns = []
+
+    runner.run(err, out)
+
+    output = out.string
+    output.gsub!(/\d+(?:\.\d+)?(s| seconds)/, "n.nnnn\\1")
+
+    caller_line = RSpec::Core::Metadata.relative_path(caller.first)
+    output.lines.reject do |line|
+      # remove the direct caller as that line is different for the summary output backtraces
+      line.include?(caller_line) ||
+
+      # ignore scirpt/rspec_with_simplecov because we don't usually have it locally but
+      # do have it on travis
+      line.include?("script/rspec_with_simplecov") ||
+
+      # this line varies a bit depending on how you run the specs (via `rake` vs `rspec`)
+      line.include?('/exe/rspec:')
+    end.join
+  end
+
+  if RUBY_VERSION.to_f < 1.9
+    def expected_summary_output_for_example_specs
+      <<-EOS.gsub(/^\s+\|/, '').chomp
+        |Pending: (Failures listed here are expected and do not affect your suite's status)
+        |
+        |  1) pending spec with no implementation is pending
+        |     # Not yet implemented
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:4
+        |
+        |  2) pending command with block format with content that would fail is pending
+        |     # No reason given
+        |     Failure/Error: expect(1).to eq(2)
+        |
+        |       expected: 2
+        |            got: 1
+        |
+        |       (compared using ==)
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:11
+        |     # ./spec/support/formatter_support.rb:13:in `run_example_specs_with_formatter'
+        |     # ./spec/support/sandboxing.rb:16
+        |     # ./spec/support/sandboxing.rb:14
+        |     # ./spec/support/sandboxing.rb:8
+        |
+        |Failures:
+        |
+        |  1) pending command with block format with content that would pass fails FIXED
+        |     Expected pending 'No reason given' to fail. No Error was raised.
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:16
+        |
+        |  2) failing spec fails
+        |     Failure/Error: expect(1).to eq(2)
+        |
+        |       expected: 2
+        |            got: 1
+        |
+        |       (compared using ==)
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:31
+        |     # ./spec/support/formatter_support.rb:13:in `run_example_specs_with_formatter'
+        |     # ./spec/support/sandboxing.rb:16
+        |     # ./spec/support/sandboxing.rb:14
+        |     # ./spec/support/sandboxing.rb:8
+        |
+        |  3) a failing spec with odd backtraces fails with a backtrace that has no file
+        |     Failure/Error: Unable to find matching line from backtrace
+        |     RuntimeError:
+        |       foo
+        |     # (erb):1
+        |
+        |  4) a failing spec with odd backtraces fails with a backtrace containing an erb file
+        |     Failure/Error: Unable to find matching line from backtrace
+        |     Exception:
+        |       Exception
+        |     # /foo.html.erb:1:in `<main>': foo (RuntimeError)
+        |
+        |Finished in n.nnnn seconds (files took n.nnnn seconds to load)
+        |7 examples, 4 failures, 2 pending
+        |
+        |Failed examples:
+        |
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:16 # pending command with block format with content that would pass fails
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:30 # failing spec fails
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:36 # a failing spec with odd backtraces fails with a backtrace that has no file
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:42 # a failing spec with odd backtraces fails with a backtrace containing an erb file
+      EOS
+    end
+  else
+    def expected_summary_output_for_example_specs
+      <<-EOS.gsub(/^\s+\|/, '').chomp
+        |Pending: (Failures listed here are expected and do not affect your suite's status)
+        |
+        |  1) pending spec with no implementation is pending
+        |     # Not yet implemented
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:4
+        |
+        |  2) pending command with block format with content that would fail is pending
+        |     # No reason given
+        |     Failure/Error: expect(1).to eq(2)
+        |
+        |       expected: 2
+        |            got: 1
+        |
+        |       (compared using ==)
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:11:in `block (3 levels) in <top (required)>'
+        |     # ./spec/support/formatter_support.rb:13:in `run_example_specs_with_formatter'
+        |     # ./spec/support/sandboxing.rb:16:in `block (4 levels) in <top (required)>'
+        |     # ./spec/support/sandboxing.rb:14:in `block (3 levels) in <top (required)>'
+        |     # ./spec/support/sandboxing.rb:8:in `block (2 levels) in <top (required)>'
+        |
+        |Failures:
+        |
+        |  1) pending command with block format with content that would pass fails FIXED
+        |     Expected pending 'No reason given' to fail. No Error was raised.
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:16
+        |
+        |  2) failing spec fails
+        |     Failure/Error: expect(1).to eq(2)
+        |
+        |       expected: 2
+        |            got: 1
+        |
+        |       (compared using ==)
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:31:in `block (2 levels) in <top (required)>'
+        |     # ./spec/support/formatter_support.rb:13:in `run_example_specs_with_formatter'
+        |     # ./spec/support/sandboxing.rb:16:in `block (4 levels) in <top (required)>'
+        |     # ./spec/support/sandboxing.rb:14:in `block (3 levels) in <top (required)>'
+        |     # ./spec/support/sandboxing.rb:8:in `block (2 levels) in <top (required)>'
+        |
+        |  3) a failing spec with odd backtraces fails with a backtrace that has no file
+        |     Failure/Error: ERB.new("<%= raise 'foo' %>").result
+        |     RuntimeError:
+        |       foo
+        |     # (erb):1:in `<main>'
+        |     # ./spec/rspec/core/resources/formatter_specs.rb:39:in `block (2 levels) in <top (required)>'
+        |     # ./spec/support/formatter_support.rb:13:in `run_example_specs_with_formatter'
+        |     # ./spec/support/sandboxing.rb:16:in `block (4 levels) in <top (required)>'
+        |     # ./spec/support/sandboxing.rb:14:in `block (3 levels) in <top (required)>'
+        |     # ./spec/support/sandboxing.rb:8:in `block (2 levels) in <top (required)>'
+        |
+        |  4) a failing spec with odd backtraces fails with a backtrace containing an erb file
+        |     Failure/Error: Unable to find matching line from backtrace
+        |     Exception:
+        |       Exception
+        |     # /foo.html.erb:1:in `<main>': foo (RuntimeError)
+        |
+        |Finished in n.nnnn seconds (files took n.nnnn seconds to load)
+        |7 examples, 4 failures, 2 pending
+        |
+        |Failed examples:
+        |
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:16 # pending command with block format with content that would pass fails
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:30 # failing spec fails
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:36 # a failing spec with odd backtraces fails with a backtrace that has no file
+        |rspec ./spec/rspec/core/resources/formatter_specs.rb:42 # a failing spec with odd backtraces fails with a backtrace containing an erb file
+      EOS
+    end
+  end
+
+  def send_notification type, notification
+    reporter.notify type, notification
+  end
+
+  def reporter
+    @reporter ||= setup_reporter
+  end
+
+  def setup_reporter(*streams)
+    config.add_formatter described_class, *streams
+    @formatter = config.formatters.first
+    @reporter = config.reporter
+  end
+
+  def output
+    @output ||= StringIO.new
+  end
+
+  def config
+    @configuration ||=
+      begin
+        config = RSpec::Core::Configuration.new
+        config.output_stream = output
+        config
+      end
+  end
+
+  def configure
+    yield config
+  end
+
+  def formatter
+    @formatter ||=
+      begin
+        setup_reporter
+        @formatter
+      end
+  end
+
+  def example
+    @example ||=
+      begin
+        result = instance_double(RSpec::Core::Example::ExecutionResult,
+                                 :pending_fixed?   => false,
+                                 :example_skipped? => false,
+                                 :status           => :passed
+                                )
+        allow(result).to receive(:exception) { exception }
+        instance_double(RSpec::Core::Example,
+                        :description       => "Example",
+                        :full_description  => "Example",
+                        :execution_result  => result,
+                        :location          => "",
+                        :rerun_argument    => "",
+                        :metadata          => {
+                          :shared_group_inclusion_backtrace => []
+                        }
+                       )
+      end
+  end
+
+  def exception
+    Exception.new
+  end
+
+  def examples(n)
+    (1..n).map { example }
+  end
+
+  def group
+    class_double "RSpec::Core::ExampleGroup", :description => "Group"
+  end
+
+  def start_notification(count)
+   ::RSpec::Core::Notifications::StartNotification.new count
+  end
+
+  def stop_notification
+   ::RSpec::Core::Notifications::ExamplesNotification.new reporter
+  end
+
+  def example_notification(specific_example = example)
+   ::RSpec::Core::Notifications::ExampleNotification.for specific_example
+  end
+
+  def group_notification
+   ::RSpec::Core::Notifications::GroupNotification.new group
+  end
+
+  def message_notification(message)
+    ::RSpec::Core::Notifications::MessageNotification.new message
+  end
+
+  def null_notification
+    ::RSpec::Core::Notifications::NullNotification
+  end
+
+  def seed_notification(seed, used = true)
+    ::RSpec::Core::Notifications::SeedNotification.new seed, used
+  end
+
+  def failed_examples_notification
+    ::RSpec::Core::Notifications::ExamplesNotification.new reporter
+  end
+
+  def summary_notification(duration, examples, failed, pending, time)
+    ::RSpec::Core::Notifications::SummaryNotification.new duration, examples, failed, pending, time
+  end
+
+  def profile_notification(duration, examples, number)
+    ::RSpec::Core::Notifications::ProfileNotification.new duration, examples, number
+  end
+
+end
diff --git a/rspec-core/spec/support/helper_methods.rb b/rspec-core/spec/support/helper_methods.rb
new file mode 100644
index 0000000..4b6abe8
--- /dev/null
+++ b/rspec-core/spec/support/helper_methods.rb
@@ -0,0 +1,26 @@
+module RSpecHelpers
+  def relative_path(path)
+    RSpec::Core::Metadata.relative_path(path)
+  end
+
+  def ignoring_warnings
+    original = $VERBOSE
+    $VERBOSE = nil
+    result = yield
+    $VERBOSE = original
+    result
+  end
+
+  def safely
+    Thread.new do
+      ignoring_warnings { $SAFE = 3 }
+      yield
+    end.join
+
+    # $SAFE is not supported on Rubinius
+    unless defined?(Rubinius)
+      expect($SAFE).to eql 0 # $SAFE should not have changed in this thread.
+    end
+  end
+
+end
diff --git a/rspec-core/spec/support/isolated_home_directory.rb b/rspec-core/spec/support/isolated_home_directory.rb
new file mode 100644
index 0000000..2f6fb94
--- /dev/null
+++ b/rspec-core/spec/support/isolated_home_directory.rb
@@ -0,0 +1,16 @@
+require 'tmpdir'
+require 'fileutils'
+
+RSpec.shared_context "isolated home directory", :isolated_home => true do
+  around do |ex|
+    Dir.mktmpdir do |tmp_dir|
+      original_home = ENV['HOME']
+      begin
+        ENV['HOME'] = tmp_dir
+        ex.call
+      ensure
+        ENV['HOME'] = original_home
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/support/matchers.rb b/rspec-core/spec/support/matchers.rb
new file mode 100644
index 0000000..b83b978
--- /dev/null
+++ b/rspec-core/spec/support/matchers.rb
@@ -0,0 +1,114 @@
+RSpec::Matchers.define :map_specs do |specs|
+  match do |autotest|
+    @specs = specs
+    @autotest = prepare(autotest)
+    autotest.test_files_for(@file) == specs
+  end
+
+  chain :to do |file|
+    @file = file
+  end
+
+  failure_message do
+    "expected #{@autotest.class} to map #{@specs.inspect} to #{@file.inspect}\ngot #{@actual.inspect}"
+  end
+
+  def prepare(autotest)
+    find_order = @specs.dup << @file
+    autotest.instance_exec { @find_order = find_order }
+    autotest
+  end
+end
+
+RSpec::Matchers.define :fail_with do |exception_klass|
+  match do |example|
+    !example.execution_result.example_skipped? &&
+    failure_reason(example, exception_klass).nil?
+  end
+
+  failure_message do |example|
+    "expected example to fail with a #{exception_klass} exception, but #{failure_reason(example, exception_klass)}"
+  end
+
+  def failure_reason(example, exception_klass)
+    result = example.execution_result
+    case
+      when example.metadata[:pending] then "was pending"
+      when result.status != :failed then result.status
+      when !result.exception.is_a?(exception_klass) then "failed with a #{result.exception.class}"
+      else nil
+    end
+  end
+end
+
+RSpec::Matchers.define :pass do
+  match do |example|
+    !example.execution_result.example_skipped? &&
+    failure_reason(example).nil?
+  end
+
+  failure_message do |example|
+    "expected example to pass, but #{failure_reason(example)}"
+  end
+
+  def failure_reason(example)
+    result = example.metadata[:execution_result]
+    case
+      when example.metadata[:pending] then "was pending"
+      when result.status != :passed then result.status
+      else nil
+    end
+  end
+end
+
+RSpec::Matchers.module_exec do
+  alias_method :have_failed_with, :fail_with
+  alias_method :have_passed, :pass
+end
+
+RSpec::Matchers.define :be_pending_with do |message|
+  match do |example|
+    example.pending? &&
+    !example.execution_result.example_skipped? &&
+    example.execution_result.pending_exception &&
+    example.execution_result.status == :pending &&
+    example.execution_result.pending_message == message
+  end
+
+  failure_message do |example|
+    "expected: example pending with #{message.inspect}\n     got: #{example.execution_result.pending_message.inspect}".tap do |msg|
+      msg << " (but had no pending exception)" unless example.execution_result.pending_exception
+    end
+  end
+end
+
+RSpec::Matchers.define :be_skipped_with do |message|
+  match do |example|
+    example.skipped? &&
+    example.pending? &&
+    example.execution_result.example_skipped? &&
+    example.execution_result.pending_message == message
+  end
+
+  failure_message do |example|
+    "expected: example skipped with #{message.inspect}\n     got: #{example.execution_result.pending_message.inspect}"
+  end
+end
+
+RSpec::Matchers.define :contain_files do |*expected_files|
+  contain_exactly_matcher = RSpec::Matchers::BuiltIn::ContainExactly.new(expected_files.map { |f| File.expand_path(f) })
+
+  match do |actual_files|
+    files = actual_files.map { |f| File.expand_path(f) }
+    contain_exactly_matcher.matches?(files)
+  end
+
+  failure_message { contain_exactly_matcher.failure_message }
+  failure_message_when_negated { contain_exactly_matcher.failure_message_when_negated }
+end
+
+RSpec::Matchers.alias_matcher :a_file_collection, :contain_files
+
+RSpec::Matchers.define_negated_matcher :avoid_outputting, :output
+RSpec::Matchers.define_negated_matcher :exclude, :include
+RSpec::Matchers.define_negated_matcher :avoid_changing,   :change
diff --git a/rspec-core/spec/support/mathn_integration_support.rb b/rspec-core/spec/support/mathn_integration_support.rb
new file mode 100644
index 0000000..f6ca400
--- /dev/null
+++ b/rspec-core/spec/support/mathn_integration_support.rb
@@ -0,0 +1,25 @@
+require 'rspec/support/spec/in_sub_process'
+
+module MathnIntegrationSupport
+  include RSpec::Support::InSubProcess
+
+  if RUBY_VERSION.to_f >= 2.2
+    def with_mathn_loaded
+      skip "lib/mathn.rb is deprecated in Ruby 2.2"
+    end
+  elsif RUBY_VERSION.to_f < 1.9
+    def with_mathn_loaded
+      in_sub_process do
+        expect { require 'mathn' }.to output.to_stderr
+        yield
+      end
+    end
+  else
+    def with_mathn_loaded
+      in_sub_process do
+        require 'mathn'
+        yield
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/support/runner_support.rb b/rspec-core/spec/support/runner_support.rb
new file mode 100644
index 0000000..d4b1d62
--- /dev/null
+++ b/rspec-core/spec/support/runner_support.rb
@@ -0,0 +1,16 @@
+module RSpec::Core
+  RSpec.shared_context "Runner support" do
+    let(:out)    { StringIO.new         }
+    let(:err)    { StringIO.new         }
+    let(:config) { RSpec.configuration  }
+    let(:world)  { RSpec.world          }
+
+    def build_runner(*args)
+      Runner.new(build_config_options(*args))
+    end
+
+    def build_config_options(*args)
+      ConfigurationOptions.new(args)
+    end
+  end
+end
diff --git a/rspec-core/spec/support/sandboxing.rb b/rspec-core/spec/support/sandboxing.rb
new file mode 100644
index 0000000..dc04bb0
--- /dev/null
+++ b/rspec-core/spec/support/sandboxing.rb
@@ -0,0 +1,21 @@
+require 'rspec/core/sandbox'
+require 'rspec/mocks'
+
+# Because testing RSpec with RSpec tries to modify the same global
+# objects, we sandbox every test.
+RSpec.configure do |c|
+  c.around do |ex|
+    RSpec::Core::Sandbox.sandboxed do |config|
+      # If there is an example-within-an-example, we want to make sure the inner example
+      # does not get a reference to the outer example (the real spec) if it calls
+      # something like `pending`
+      config.before(:context) { RSpec.current_example = nil }
+
+      RSpec::Mocks.with_temporary_scope do
+        orig_load_path = $LOAD_PATH.dup
+        ex.run
+        $LOAD_PATH.replace(orig_load_path)
+      end
+    end
+  end
+end
diff --git a/rspec-core/spec/support/shared_example_groups.rb b/rspec-core/spec/support/shared_example_groups.rb
new file mode 100644
index 0000000..4a732c1
--- /dev/null
+++ b/rspec-core/spec/support/shared_example_groups.rb
@@ -0,0 +1,47 @@
+RSpec.shared_examples_for "metadata hash builder" do
+  let(:hash) { metadata_hash(:foo, :bar, :bazz => 23) }
+
+  it 'treats symbols as metadata keys with a true value' do
+    expect(hash[:foo]).to be(true)
+    expect(hash[:bar]).to be(true)
+  end
+
+  it 'still processes hash values normally' do
+    expect(hash[:bazz]).to be(23)
+  end
+end
+
+RSpec.shared_examples_for "handling symlinked directories when loading spec files" do
+  include_context "isolated directory"
+  let(:project_dir) { Dir.getwd }
+
+  before(:example) do
+    pending "Windows does not support symlinking"
+  end if RSpec::Support::OS.windows?
+
+  it "finds the files" do
+    foos_dir = File.join(project_dir, "spec/foos")
+    FileUtils.mkdir_p foos_dir
+    FileUtils.touch(File.join(foos_dir, "foo_spec.rb"))
+
+    bars_dir = File.join(Dir.tmpdir, "shared/spec/bars")
+    FileUtils.mkdir_p bars_dir
+    FileUtils.touch(File.join(bars_dir, "bar_spec.rb"))
+
+    FileUtils.ln_s bars_dir, File.join(project_dir, "spec/bars")
+
+    expect(loaded_files).to contain_files(
+      "spec/bars/bar_spec.rb",
+      "spec/foos/foo_spec.rb"
+    )
+  end
+
+  it "works on a more complicated example (issue 1113)" do
+    FileUtils.mkdir_p("subtrees/DD/spec")
+    FileUtils.mkdir_p("spec/lib")
+    FileUtils.touch("subtrees/DD/spec/dd_foo_spec.rb")
+    FileUtils.ln_s(File.join(project_dir, "subtrees/DD/spec"), "spec/lib/DD")
+
+    expect(loaded_files).to contain_files("spec/lib/DD/dd_foo_spec.rb")
+  end
+end
diff --git a/rspec-core/spec/support/spec_files.rb b/rspec-core/spec/support/spec_files.rb
new file mode 100644
index 0000000..a9f89f1
--- /dev/null
+++ b/rspec-core/spec/support/spec_files.rb
@@ -0,0 +1,44 @@
+RSpec.shared_context "spec files" do
+  def failing_spec_filename
+    @failing_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_failing_spec.rb"
+  end
+
+  def passing_spec_filename
+    @passing_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_passing_spec.rb"
+  end
+
+  def create_passing_spec_file
+    File.open(passing_spec_filename, 'w') do |f|
+      f.write %q{
+        RSpec.describe "passing spec" do
+          it "passes" do
+            expect(1).to eq(1)
+          end
+        end
+      }
+    end
+  end
+
+  def create_failing_spec_file
+    File.open(failing_spec_filename, 'w') do |f|
+      f.write %q{
+        RSpec.describe "failing spec" do
+          it "fails" do
+            expect(1).to eq(2)
+          end
+        end
+      }
+    end
+  end
+
+  before(:all) do
+    create_passing_spec_file
+    create_failing_spec_file
+  end
+
+  after(:all) do
+    File.delete(passing_spec_filename)
+    File.delete(failing_spec_filename)
+  end
+
+end
diff --git a/rspec-expectations/.document b/rspec-expectations/.document
new file mode 100644
index 0000000..050e204
--- /dev/null
+++ b/rspec-expectations/.document
@@ -0,0 +1,5 @@
+lib/**/*.rb
+-
+README.md
+License.txt
+Changelog.md
diff --git a/rspec-expectations/.gitignore b/rspec-expectations/.gitignore
new file mode 100644
index 0000000..1243eae
--- /dev/null
+++ b/rspec-expectations/.gitignore
@@ -0,0 +1,17 @@
+*.sw?
+.DS_Store
+coverage*
+rdoc
+pkg
+doc
+tmp
+rerun.txt
+Gemfile.lock
+.bundle
+*.rbc
+.yardoc
+bin
+.rbx
+Gemfile-custom
+bundle
+.rspec-local
diff --git a/rspec-expectations/.rspec b/rspec-expectations/.rspec
new file mode 100644
index 0000000..d0f7279
--- /dev/null
+++ b/rspec-expectations/.rspec
@@ -0,0 +1,2 @@
+--warnings
+--require spec_helper
diff --git a/rspec-expectations/.rubocop.yml b/rspec-expectations/.rubocop.yml
new file mode 100644
index 0000000..a9e9058
--- /dev/null
+++ b/rspec-expectations/.rubocop.yml
@@ -0,0 +1,5 @@
+inherit_from: .rubocop_rspec_base.yml
+
+# Over time we'd like to get this down, but this is what we're at now.
+LineLength:
+  Max: 186
diff --git a/rspec-expectations/.rubocop_rspec_base.yml b/rspec-expectations/.rubocop_rspec_base.yml
new file mode 100644
index 0000000..f7bea1c
--- /dev/null
+++ b/rspec-expectations/.rubocop_rspec_base.yml
@@ -0,0 +1,130 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# This file contains defaults for RSpec projects. Individual projects
+# can customize by inheriting this file and overriding particular settings.
+
+AccessModifierIndentation:
+  EnforcedStyle: outdent
+
+# "Use alias_method instead of alias"
+# We're fine with `alias`.
+Alias:
+  Enabled: false
+
+AlignParameters:
+  EnforcedStyle: with_first_parameter
+
+# "Avoid the use of the case equality operator ==="
+# We prefer using `Class#===` over `Object#is_a?` because `Class#===`
+# is less likely to be monkey patched than `is_a?` on a user object.
+CaseEquality:
+  Enabled: false
+
+# Warns when the class is excessively long.
+ClassLength:
+  Max: 100
+
+CollectionMethods:
+  PreferredMethods:
+    reduce: 'inject'
+
+# Over time we'd like to get this down, but this is what we're at now.
+CyclomaticComplexity:
+  Max: 10
+
+# We use YARD to enforce documentation. It works better than rubocop's
+# enforcement...rubocop complains about the places we re-open
+# `RSpec::Expectations` and `RSpec::Matchers` w/o having doc commments.
+Documentation:
+  Enabled: false
+
+# We still support 1.8.7 which requires trailing dots
+DotPosition:
+  EnforcedStyle: trailing
+
+DoubleNegation:
+  Enabled: false
+
+# each_with_object is unavailable on 1.8.7 so we have to disable this one.
+EachWithObject:
+  Enabled: false
+
+Encoding:
+  EnforcedStyle: when_needed
+
+FormatString:
+  EnforcedStyle: percent
+
+# As long as we support ruby 1.8.7 we have to use hash rockets.
+HashSyntax:
+  EnforcedStyle: hash_rockets
+
+# We can't use the new lambda syntax, since we still support 1.8.7.
+Lambda:
+  Enabled: false
+
+# Over time we'd like to get this down, but this is what we're at now.
+LineLength:
+  Max: 100
+
+# Over time we'd like to get this down, but this is what we're at now.
+MethodLength:
+  Max: 15
+
+# Who cares what we call the argument for binary operator methods?
+OpMethod:
+  Enabled: false
+
+PercentLiteralDelimiters:
+  PreferredDelimiters:
+    '%':  ()      # double-quoted string
+    '%i': '[]'    # array of symbols
+    '%q': ()      # single-quoted string
+    '%Q': ()      # double-quoted string
+    '%r': '{}'    # regular expression pattern
+    '%s': ()      # a symbol
+    '%w': '[]'    # array of single-quoted strings
+    '%W': '[]'    # array of double-quoted strings
+    '%x': ()      # a shell command as a string
+
+# We have too many special cases where we allow generator methods or prefer a
+# prefixed predicate due to it's improved readability.
+PredicateName:
+  Enabled: false
+
+# On 1.8 `proc` is `lambda`, so we use `Proc.new` to ensure we get real procs on all supported versions.
+# http://batsov.com/articles/2014/02/04/the-elements-of-style-in-ruby-number-12-proc-vs-proc-dot-new/
+Proc:
+  Enabled: false
+
+RedundantReturn:
+  AllowMultipleReturnValues: true
+
+# We have to rescue Exception in the `raise_error` matcher for it to work properly.
+RescueException:
+  Enabled: false
+
+# We haven't adopted the `fail` to signal exceptions vs `raise` for re-raises convention.
+SignalException:
+  Enabled: false
+
+# We've tended to use no space, so it's less of a change to stick with that.
+SpaceAroundEqualsInParameterDefault:
+  EnforcedStyle: no_space
+
+# We don't care about single vs double qoutes.
+StringLiterals:
+  Enabled: false
+
+# This rule favors constant names from the English standard library which we don't load.
+Style/SpecialGlobalVars:
+  Enabled: false
+
+Style/TrailingComma:
+  Enabled: false
+
+TrivialAccessors:
+  AllowDSLWriters: true
+  AllowPredicates: true
+  ExactNameMatch: true
diff --git a/rspec-expectations/.travis.yml b/rspec-expectations/.travis.yml
new file mode 100644
index 0000000..ea4f1b0
--- /dev/null
+++ b/rspec-expectations/.travis.yml
@@ -0,0 +1,37 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+language: ruby
+sudo: false
+cache:
+  directories:
+    - ../bundle
+before_install:
+  - "script/clone_all_rspec_repos"
+  # Downgrade bundler to work around https://github.com/bundler/bundler/issues/3004
+  # Note this doesn't work on JRUBY 2.0.0 mode so we don't do it
+  - if [ -z "$JRUBY_OPTS" ]; then gem install bundler -v=1.5.3 && alias bundle="bundle _1.5.3_"; fi
+bundler_args: "--binstubs --standalone --without documentation --path ../bundle"
+script: "script/run_build"
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - 2.1
+  - 2.2
+  - ruby-head
+  - ree
+  - jruby-18mode
+  - jruby
+  - jruby-head
+  - rbx
+matrix:
+  include:
+    - rvm: jruby
+      env: JRUBY_OPTS='--2.0'
+  allow_failures:
+    - rvm: jruby-head
+    - rvm: ruby-head
+    - rvm: rbx
+  fast_finish: true
diff --git a/rspec-expectations/.yardopts b/rspec-expectations/.yardopts
new file mode 100644
index 0000000..15f63ee
--- /dev/null
+++ b/rspec-expectations/.yardopts
@@ -0,0 +1,6 @@
+--exclude features
+--no-private
+--markup markdown
+-
+Changelog.md
+License.txt
diff --git a/rspec-expectations/Changelog.md b/rspec-expectations/Changelog.md
new file mode 100644
index 0000000..aab7530
--- /dev/null
+++ b/rspec-expectations/Changelog.md
@@ -0,0 +1,880 @@
+### 3.2.0 / 2015-02-03
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.2...v3.2.0)
+
+Enhancements:
+
+* Add `block_arg` method to custom matcher API, which allows you to
+  access the block passed to a custom matcher, if there is one.
+  (Mike Dalton, #645)
+* Provide more detail in failure message of `yield_control` matcher.
+  (Jon Rowe, #650)
+* Add a shorthand syntax for `chain` in the matcher DSL which assigns values
+  for use elsewhere, for example `chain :and_smaller_than, :small_value`
+  creates an `attr_reader` for `small_value` (Tom Stuart, #644)
+* Provide a more helpful deprecation message when using the `should` syntax.
+  (Elia Schito, #663)
+* Provide more detail in the `have_attributes` matcher failure message.
+  (Jon Rowe,  #668)
+* Make the `have_attributes` matcher diffable.
+  (Jon Rowe, Alexey Fedorov, #668)
+* Add `output(...).to_std(out|err)_from_any_process` as alternatives
+  to `output(...).to_std(out|err)`. The latter doesn't work when a sub
+  process writes to the named stream but is much faster.
+  (Alex Genco, #700)
+* Improve compound matchers (created by `and` and `or`) so that diffs
+  are included in failures when one or more of their matchers
+  are diffable. (Alexey Fedorov, #713)
+
+Bug Fixes:
+
+* Avoid calling `private_methods` from the `be` predicate matcher on
+  the target object if the object publicly responds to the predicate
+  method. This avoids a possible error that can occur if the object
+  raises errors from `private_methods` (which can happen with celluloid
+  objects). (@chapmajs, #670)
+* Make `yield_control` (with no modifier) default to
+  `at_least(:once)` rather than raising a confusing error
+  when multiple yields are encountered.
+  (Myron Marston, #675)
+* Fix "instance variable @color not initialized" warning when using
+  rspec-expectations outside of an rspec-core context. (Myron Marston, #689)
+* Fix `start_with` and `end_with` to work properly when checking a
+  string against an array of strings. (Myron Marston, #690)
+* Don't use internally delegated matchers when generating descriptions
+  for examples without doc strings. (Myron Marston, #692)
+
+### 3.1.2 / 2014-09-26
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.1...v3.1.2)
+
+Bug Fixes:
+
+* Fix `define_negated_matcher` so that matchers that support fluent
+  interfaces continue to be negated after you use the chained method.
+  (Myron Marston, #656)
+* Fix `define_negated_matcher` so that the matchers fail with an
+  appropriate failure message. (Myron Marston, #659)
+
+### 3.1.1 / 2014-09-15
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.0...v3.1.1)
+
+Bug Fixes:
+
+* Fix regression in `all` matcher in 3.1.0 that prevented it from
+  working on objects that are not `Enumerable` but do implement
+  `each_with_index` (such as an ActiveRecord proxy). (Jori Hardman, #647)
+
+### 3.1.0 / 2014-09-04
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.4...v3.1.0)
+
+Enhancements:
+
+* Add `have_attributes` matcher, that passes if actual's attribute
+  values match the expected attributes hash:
+  `Person = Struct.new(:name, :age)`
+  `person = Person.new("Bob", 32)`
+  `expect(person).to have_attributes(:name => "Bob", :age => 32)`.
+  (Adam Farhi, #571)
+* Extended compound matcher support to block matchers, for cases like:
+  `expect { ... }.to change { x }.to(3).and change { y }.to(4)`. (Myron
+  Marston, #567)
+* Include chained methods in custom matcher description and failure message
+  when new `include_chain_clauses_in_custom_matcher_descriptions` config
+  option is enabled. (Dan Oved, #600)
+* Add `thrice` modifier to `yield_control` matcher as a synonym for
+  `exactly(3).times`. (Dennis Taylor, #615)
+* Add `RSpec::Matchers.define_negated_matcher`, which defines a negated
+  version of the named matcher. (Adam Farhi, Myron Marston, #618)
+* Document and support negation of `contain_exactly`/`match_array`.
+  (Jon Rowe, #626).
+
+Bug Fixes:
+
+* Rename private `LegacyMacherAdapter` constant to `LegacyMatcherAdapter`
+  to fix typo. (Abdelkader Boudih, #563)
+* Fix `all` matcher so that it fails properly (rather than raising a
+  `NoMethodError`) when matched against a non-enumerable. (Hao Su, #622)
+
+### 3.0.4 / 2014-08-14
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.3...v3.0.4)
+
+Bug Fixes:
+
+* Fix `start_with` and `end_with` so that they work properly with
+  structs. (Myron Marston, #620)
+* Fix failure message generation so that structs are printed properly
+  in failures. Previously failure messages would represent them as
+  an array. (Myron Marston, #620)
+* Fix composable matcher support so that it does not wrongly treat
+  structs as arrays. (Myron Marston, #620)
+
+### 3.0.3 / 2014-07-21
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.2...v3.0.3)
+
+Bug Fixes:
+
+* Fix issue with detection of generic operator matchers so they work
+  correctly when undefined. (Myron Marston, #597)
+* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, #603)
+* Fix `include` matcher so that it fails gracefully when matched against
+  an object that does not respond to `include?`. (Myron Marston, #607)
+
+### 3.0.2 / 2014-06-19
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.1...v3.0.2)
+
+Bug Fixes:
+
+* Fix regression in `contain_exactly` (AKA `match_array`) that caused it
+  to wrongly pass when the expected array was empty. (Myron Marston, #581)
+* Provide a better error message when you use the `change(obj, :msg)`
+  form of the change matcher but forget the message argument. (Alex
+  Sunderland, #585)
+* Make the `contain_exactly` matcher work with arrays that contain hashes in
+  arbitrary ordering. (Sam Phippen, #578)
+
+### 3.0.1 / 2014-06-12
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0...v3.0.1)
+
+Bug Fixes:
+
+* Add a missing `require` that would cause the `respond_to` matcher to
+  fail when used in a project where the rest of RSpec (e.g. core and
+  expecatations) weren't being used. (Myron Marston, #566)
+* Structs are no longer treated as arrays when diffed. (Jon Rowe, #576)
+
+### 3.0.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.rc1...v3.0.0)
+
+No code changes. Just taking it out of pre-release.
+
+### 3.0.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta2...v3.0.0.rc1)
+
+Breaking Changes for 3.0.0:
+
+* Remove `matcher_execution_context` attribute from DSL-defined
+  custom matchers. (Myron Marston)
+* Remove `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston)
+* Remove `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston)
+* Rename `RSpec::Matchers::Configuration` constant to
+  `RSpec::Expectations::Configuration`. (Myron Marston)
+* Prevent `have_xyz` predicate matchers using private methods.
+  (Adrian Gonzalez)
+* Block matchers must now implement `supports_block_expectations?`.
+  (Myron Marston)
+* Stop supporting `require 'rspec-expectations'`.
+  Use `require 'rspec/expectations'` instead. (Myron Marston)
+
+Bug Fixes:
+
+* Fix `NoMethodError` triggered by beta2 when `YARD` was loaded in
+  the test environment. (Myron Marston)
+* Fix `be_xyz` matcher to accept a `do...end` block. (Myron Marston)
+* Fix composable matcher failure message generation logic
+  so that it does not blow up when given `$stdout` or `$stderr`.
+  (Myron Marston)
+* Fix `change` matcher to work properly with `IO` objects.
+  (Myron Marston)
+* Fix `exist` matcher so that it can be used in composed matcher
+  expressions involving objects that do not implement `exist?` or
+  `exists?`. (Daniel Fone)
+* Fix composable matcher match logic so that it clones matchers
+  before using them in order to work properly with matchers
+  that use internal memoization based on a given `actual` value.
+  (Myron Marston)
+* Fix `be_xyz` and `has_xyz` predicate matchers so that they can
+  be used in composed matcher expressions involving objects that
+  do not implement the predicate method. (Daniel Fone)
+
+Enhancements:
+
+* Document the remaining public APIs. rspec-expectations now has 100% of
+  the public API documented and will remain that way (as new undocumented
+  methods will fail the build). (Myron Marston)
+* Improve the formatting of BigDecimal objects in `eq` matcher failure
+  messages. (Daniel Fone)
+* Improve the failure message for `be_xyz` predicate matchers so
+  that it includes the `inspect` output of the receiver.
+  (Erik Michaels-Ober, Sam Phippen)
+* Add `all` matcher, to allow you to specify that a given matcher
+  matches all elements in a collection:
+  `expect([1, 3, 5]).to all( be_odd )`. (Adam Farhi)
+* Add boolean aliases (`&`/`|`) for compound operators (`and`/`or`). (Adam Farhi)
+* Give users a clear error when they wrongly use a value matcher
+  in a block expectation expression (e.g. `expect { 3 }.to eq(3)`)
+  or vice versa.  (Myron Marston)
+
+### 3.0.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta1...v3.0.0.beta2)
+
+Breaking Changes for 3.0.0:
+
+* Remove deprecated support for accessing the `RSpec` constant using
+  `Rspec` or `Spec`. (Myron Marston)
+* Remove deprecated `RSpec::Expectations.differ=`. (Myron Marston)
+* Remove support for deprecated `expect(...).should`. (Myron Marston)
+* Explicitly disallow `expect { }.not_to change { }` with `by`,
+  `by_at_least`, `by_at_most` or `to`. These have never been supported
+  but did not raise explicit errors. (Myron Marston)
+* Provide `===` rather than `==` as an alias of `matches?` for
+  all matchers.  The semantics of `===` are closer to an RSpec
+  matcher than `==`. (Myron Marston)
+* Remove deprecated `RSpec::Matchers::OperatorMatcher` constant.
+  (Myron Marston)
+* Make `RSpec::Expectations::ExpectationNotMetError` subclass
+  `Exception` rather than `StandardError` so they can bypass
+  a bare `rescue` in end-user code (e.g. when an expectation is
+  set from within a rspec-mocks stub implementation). (Myron Marston)
+* Remove Test::Unit and Minitest 4.x integration. (Myron Marston)
+
+Enhancements:
+
+* Simplify the failure message of the `be` matcher when matching against:
+  `true`, `false` and `nil`. (Sam Phippen)
+* Update matcher protocol and custom matcher DSL to better align
+  with the newer `expect` syntax. If you want your matchers to
+  maintain compatibility with multiple versions of RSpec, you can
+  alias the new names to the old. (Myron Marston)
+    * `failure_message_for_should` => `failure_message`
+    * `failure_message_for_should_not` => `failure_message_when_negated`
+    * `match_for_should` => `match`
+    * `match_for_should_not` => `match_when_negated`
+* Improve generated descriptions from `change` matcher. (Myron Marston)
+* Add support for compound matcher expressions using `and` and `or`.
+  Simply chain them off of any existing matcher to create an expression
+  like `expect(alphabet).to start_with("a").and end_with("z")`.
+  (Eloy Espinaco)
+* Add `contain_exactly` as a less ambiguous version of `match_array`.
+  Note that it expects the expected array to be splatted as
+  individual args: `expect(array).to contain_exactly(1, 2)` is
+  the same as `expect(array).to match_array([1, 2])`. (Myron Marston)
+* Update `contain_exactly`/`match_array` so that it can match against
+  other non-array collections (such as a `Set`). (Myron Marston)
+* Update built-in matchers so that they can accept matchers as arguments
+  to allow you to compose matchers in arbitrary ways. (Myron Marston)
+* Add `RSpec::Matchers::Composable` mixin that can be used to make
+  a custom matcher composable as well. Note that custom matchers
+  defined via `RSpec::Matchers.define` already have this. (Myron
+  Marston)
+* Define noun-phrase aliases for built-in matchers, which can be
+  used when creating composed matcher expressions that read better
+  and provide better failure messages. (Myron Marston)
+* Add `RSpec::Matchers.alias_matcher` so users can define their own
+  matcher aliases. The `description` of the matcher will reflect the
+  alternate matcher name. (Myron Marston)
+* Add explicit `be_between` matcher. `be_between` has worked for a
+  long time as a dynamic predicate matcher, but the failure message
+  was suboptimal. The new matcher provides a much better failure
+  message. (Erik Michaels-Ober)
+* Enhance the `be_between` matcher to allow for `inclusive` or `exclusive`
+  comparison (e.g. inclusive of min/max or exclusive of min/max).
+  (Pedro Gimenez)
+* Make failure message for `not_to be #{operator}` less confusing by
+  only saying it's confusing when comparison operators are used.
+  (Prathamesh Sonpatki)
+* Improve failure message of `eq` matcher when `Time` or `DateTime`
+  objects are used so that the full sub-second precision is included.
+  (Thomas Holmes, Jeff Wallace)
+* Add `output` matcher for expecting that a block outputs `to_stdout`
+  or `to_stderr`. (Luca Pette, Matthias Günther)
+* Forward a provided block on to the `has_xyz?` method call when
+  the `have_xyz` matcher is used. (Damian Galarza)
+* Provide integration with Minitest 5.x. Require
+  `rspec/expectations/minitest_integration` after loading minitest
+  to use rspec-expectations with minitest. (Myron Marston)
+
+Bug Fixes:
+
+* Fix wrong matcher descriptions with falsey expected value (yujinakayama)
+* Fix `expect { }.not_to change { }.from(x)` so that the matcher only
+  passes if the starting value is `x`. (Tyler Rick, Myron Marston)
+* Fix hash diffing, so that it colorizes properly and doesn't consider trailing
+  commas when performing the diff. (Jared Norman)
+* Fix built-in matchers to fail normally rather than raising
+  `ArgumentError` when given an object of the wrong type to match
+  against, so that they work well in composite matcher expressions like
+  `expect([1.51, "foo"]).to include(a_string_matching(/foo/), a_value_within(0.1).of(1.5))`.
+  (Myron Marston)
+
+Deprecations:
+
+* Retain support for RSpec 2 matcher protocol (e.g. for matchers
+  in 3rd party extension gems like `shoulda`), but it will print
+  a deprecation warning. (Myron Marston)
+
+### 3.0.0.beta1 / 2013-11-07
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.2...v3.0.0.beta1)
+
+Breaking Changes for 3.0.0:
+
+* Remove explicit support for 1.8.6. (Jon Rowe)
+* Remove the deprecated `be_close` matcher, preferring `be_within` instead.
+  (Sam Phippen)
+* Remove the deprecated `have`, `have_at_least` and `have_at_most` matchers.
+  You can continue using those matchers through https://github.com/rspec/rspec-collection_matchers,
+  or you can rewrite your expectations with something like 
+  `expect(your_object.size).to eq(num)`. (Hugo Baraúna)
+* Rename `be_true` and `be_false` to `be_truthy` and `be_falsey`. (Sam Phippen)
+* Make `expect { }.to_not raise_error(SomeSpecificClass, message)`,
+       `expect { }.to_not raise_error(SomeSpecificClass)` and
+       `expect { }.to_not raise_error(message)` invalid, since they are prone
+  to hiding failures. Instead, use `expect { }.to_not raise_error` (with no
+  args). (Sam Phippen)
+* Within `RSpec::Matchers.define` blocks, helper methods made available
+  either via `def self.helper` or `extend HelperModule` are no longer
+  available to the `match` block (or any of the others). Instead
+  `include` your helper module and define the helper method as an
+  instance method. (Myron Marston)
+* Force upgrading Diff::LCS for encoding compatability with diffs. (Jon Rowe)
+
+Enhancements:
+
+* Support `do..end` style block with `raise_error` matcher. (Yuji Nakayama)
+* Rewrote custom matcher DSL to simplify its implementation and solve a
+  few issues. (Myron Marston)
+* Allow early `return` from within custom matcher DSL blocks. (Myron
+  Marston)
+* The custom matcher DSL's `chain` can now accept a block. (Myron
+  Marston)
+* Support setting an expectation on a `raise_error` matcher via a chained
+  `with_message` method call. (Sam Phippen)
+
+Bug Fixes:
+
+* Allow `include` and `match` matchers to be used from within a
+  DSL-defined custom matcher's `match` block. (Myron Marston)
+* Correct encoding error message on diff failure (Jon Rowe)
+
+Deprecations:
+
+ * Using the old `:should` syntax without explicitly configuring it is deprecated.
+   It will continue to work but will emit a deprecation warning in RSpec 3 if
+   you do not explicitly enable it. (Sam Phippen)
+
+### 2.99.2 / 2014-07-21
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.1...v2.99.2)
+
+Bug Fixes:
+
+* Fix regression in `Expectations#method_handle_for` where proxy objects
+  with method delegated would wrongly not return a method handle.
+  (Jon Rowe, #594)
+* Fix issue with detection of generic operator matchers so they work
+  correctly when undefined. (Myron Marston, #597)
+
+### 2.99.1 / 2014-06-19
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0...v2.99.1)
+
+Bug Fixes:
+
+* Fix typo in custom matcher `expected` deprecation warning -- it's
+  `expected_as_array`, not `expected_array`. (Frederick Cheung, #562)
+
+### 2.99.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.rc1...v2.99.0)
+
+Enhancements:
+
+* Special case deprecation message for `errors_on` with `rspec-rails` to be more useful.
+  (Aaron Kromer)
+
+### 2.99.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta2...2.99.0.rc1)
+
+Deprecations:
+
+* Deprecate `matcher_execution_context` attribute on DSL-defined
+  custom matchers. (Myron Marston)
+* Deprecate `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston)
+* Deprecate `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston)
+* Deprecate `RSpec::Matchers::Configuration` in favor of
+  `RSpec::Expectations::Configuration`. (Myron Marston)
+* Deprecate `be_xyz` predicate matcher on an object that doesn't respond to
+  `xyz?` or `xyzs?`. (Daniel Fone)
+* Deprecate `have_xyz` matcher on an object that doesn't respond to `has_xyz?`.
+  (Daniel Fone)
+* Deprecate `have_xyz` matcher on an object that has a private method `has_xyz?`.
+  (Jon Rowe)
+* Issue a deprecation warning when a block expectation expression is
+  used with a matcher that doesn't explicitly support block expectations
+  via `supports_block_expectations?`. (Myron Marston)
+* Deprecate `require 'rspec-expectations'`. Use
+  `require 'rspec/expectations'` instead. (Myron Marston)
+
+### 2.99.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta1...v2.99.0.beta2)
+
+Deprecations:
+
+* Deprecate chaining `by`, `by_at_least`, `by_at_most` or `to` off of
+  `expect { }.not_to change { }`. The docs have always said these are
+  not supported for the negative form but now they explicitly raise
+  errors in RSpec 3. (Myron Marston)
+* Change the semantics of `expect { }.not_to change { x }.from(y)`.
+  In RSpec 2.x, this expectation would only fail if `x` started with
+  the value of `y` and changed. If it started with a different value
+  and changed, it would pass. In RSpec 3, it will pass only if the
+  value starts at `y` and it does not change. (Myron Marston)
+* Deprecate `matcher == value` as an alias for `matcher.matches?(value)`,
+  in favor of `matcher === value`. (Myron Marston)
+* Deprecate `RSpec::Matchers::OperatorMatcher` in favor of
+  `RSpec::Matchers::BuiltIn::OperatorMatcher`. (Myron Marston)
+* Deprecate auto-integration with Test::Unit and minitest.
+  Instead, include `RSpec::Matchers` in the appropriate test case
+  base class yourself. (Myron Marston)
+* Deprecate treating `#expected` on a DSL-generated custom matcher
+  as an array when only 1 argument is passed to the matcher method.
+  In RSpec 3 it will be the single value in order to make diffs
+  work properly. (Jon Rowe)
+
+### 2.99.0.beta1 / 2013-11-07
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.99.0.beta1)
+
+Deprecations
+
+* Deprecate `have`, `have_at_least` and `have_at_most`. You can continue using those
+	matchers through https://github.com/rspec/rspec-collection_matchers, or
+	you can rewrite your expectations with something like
+	`expect(your_object.size).to eq(num)`. (Hugo Baraúna)
+* Deprecate `be_xyz` predicate matcher when `xyz?` is a private method.
+  (Jon Rowe)
+* Deprecate `be_true`/`be_false` in favour of `be_truthy`/`be_falsey`
+  (for Ruby's conditional semantics) or `be true`/`be false`
+  (for exact equality). (Sam Phippen)
+* Deprecate calling helper methods from a custom matcher with the wrong
+  scope. (Myron Marston)
+  * `def self.foo` / `extend Helper` can be used to add macro methods
+    (e.g. methods that call the custom matcher DSL methods), but should
+    not be used to define helper methods called from within the DSL
+    blocks.
+  * `def foo` / `include Helper` is the opposite: it's for helper methods
+    callable from within a DSL block, but not for defining macros.
+  * RSpec 2.x allowed helper methods defined either way to be used for
+    either purpose, but RSpec 3.0 will not.
+
+### 2.14.5 / 2014-02-01
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.14.5)
+
+Bug fixes
+
+* Fix wrong matcher descriptions with falsey expected value
+  (yujinakayama)
+
+### 2.14.4 / 2013-11-06
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.3...v2.14.4)
+
+Bug fixes
+
+* Make the `match` matcher produce a diff output. (Jon Rowe, Ben Moss)
+* Choose encoding for diff's more intelligently, and when all else fails fall
+  back to default internal encoding with replacing characters. (Jon Rowe)
+
+### 2.14.3 / 2013-09-22
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.2...v2.14.3)
+
+Bug fixes
+
+* Fix operator matchers (`should` syntax) when `method` is redefined on target.
+  (Brandon Turner)
+* Fix diffing of hashes with object based keys. (Jon Rowe)
+* Fix operator matchers (`should` syntax) when operator is defined via
+  `method_missing` (Jon Rowe)
+
+### 2.14.2 / 2013-08-14
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.1...v2.14.2)
+
+Bug fixes
+
+* Fix `be_<predicate>` matcher to not support operator chaining like the
+  `be` matcher does (e.g. `be == 5`). This led to some odd behaviors
+  since `be_<predicate> == anything` returned a `BeComparedTo` matcher
+  and was thus always truthy. This was a consequence of the implementation
+  (e.g. subclassing the basic `Be` matcher) and was not intended behavior.
+  (Myron Marston).
+* Fix `change` matcher to compare using `==` in addition to `===`. This
+  is important for an expression like:
+  `expect {}.to change { a.class }.from(ClassA).to(ClassB)` because
+  `SomeClass === SomeClass` returns false. (Myron Marston)
+
+### 2.14.1 / 2013-08-08
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0...2.14.1)
+
+Bug fixes
+
+* Ensure diff output uses the same encoding as the encoding of
+  the string being diff'd to prevent `Encoding::UndefinedConversionError`
+  errors (Jon Rowe).
+
+### 2.14.0 / 2013-07-06
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0.rc1...v2.14.0)
+
+Bug fixes
+
+* Values that are not matchers use `#inspect`, rather than `#description` for
+  documentation output (Andy Lindeman, Sam Phippen).
+* Make `expect(a).to be_within(x).percent_of(y)` work with negative y
+  (Katsuhiko Nishimra).
+* Make the `be_predicate` matcher work as expected used with `expect{...}.to
+  change...`  (Sam Phippen).
+
+### 2.14.0.rc1 / 2013-05-27
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.13.0...v2.14.0.rc1)
+
+Enhancements
+
+* Enhance `yield_control` so that you can specify an exact or relative
+  number of times: `expect { }.to yield_control.exactly(3).times`,
+  `expect { }.to yield_control.at_least(2).times`, etc (Bartek
+  Borkowski).
+* Make the differ that is used when an expectation fails better handle arrays
+  by splitting each element of the array onto its own line. (Sam Phippen)
+* Accept duck-typed strings that respond to `:to_str` as expectation messages.
+  (Toby Ovod-Everett)
+
+Bug fixes
+
+* Fix differ to not raise errors when dealing with differently-encoded
+  strings (Jon Rowe).
+* Fix `expect(something).to be_within(x).percent_of(y)` where x and y are both
+  integers (Sam Phippen).
+* Fix `have` matcher to handle the fact that on ruby 2.0,
+  `Enumerator#size` may return nil (Kenta Murata).
+* Fix `expect { raise s }.to raise_error(s)` where s is an error instance
+  on ruby 2.0 (Sam Phippen).
+* Fix `expect(object).to raise_error` passing. This now warns the user and
+  fails the spec (tomykaira).
+
+Deprecations
+
+* Deprecate `expect { }.not_to raise_error(SpecificErrorClass)` or
+  `expect { }.not_to raise_error("some specific message")`. Using
+  these was prone to hiding failures as they would allow _any other
+  error_ to pass. (Sam Phippen and David Chelimsky)
+
+### 2.13.0 / 2013-02-23
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.1...v2.13.0)
+
+Enhancements
+
+* Add support for percent deltas to `be_within` matcher:
+  `expect(value).to be_within(10).percent_of(expected)`
+  (Myron Marston).
+* Add support to `include` matcher to allow it to be given a list
+  of matchers as the expecteds to match against (Luke Redpath).
+
+Bug fixes
+
+* Fix `change` matcher so that it dups strings in order to handle
+  mutated strings (Myron Marston).
+* Fix `should be =~ /some regex/` / `expect(...).to be =~ /some regex/`.
+  Previously, these either failed with a confusing `undefined method
+  matches?' for false:FalseClass` error or were no-ops that didn't
+  actually verify anything (Myron Marston).
+* Add compatibility for diff-lcs 1.2 and relax the version
+  constraint (Peter Goldstein).
+* Fix DSL-generated matchers to allow multiple instances of the
+  same matcher in the same example to have different description
+  and failure messages based on the expected value (Myron Marston).
+* Prevent `undefined method #split for Array` error when dumping
+  the diff of an array of multiline strings (Myron Marston).
+* Don't blow up when comparing strings that are in an encoding
+  that is not ASCII compatible (Myron Marston).
+* Remove confusing "Check the implementation of #==" message
+  printed for empty diffs (Myron Marston).
+
+### 2.12.1 / 2012-12-15
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.0...v2.12.1)
+
+Bug fixes
+
+* Improve the failure message for an expression like
+  `{}.should =~ {}`. (Myron Marston and Andy Lindeman)
+* Provide a `match_regex` alias so that custom matchers
+  built using the matcher DSL can use it (since `match`
+  is a different method in that context).
+  (Steven Harman)
+
+### 2.12.0 / 2012-11-12
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.3...v2.12.0)
+
+Enhancements
+
+* Colorize diffs if the `--color` option is configured. (Alex Coplan)
+* Include backtraces in unexpected errors handled by `raise_error`
+  matcher (Myron Marston)
+* Print a warning when users accidentally pass a non-string argument
+  as an expectation message (Sam Phippen)
+* `=~` and `match_array` matchers output a more useful error message when
+  the actual value is not an array (or an object that responds to `#to_ary`)
+  (Sam Phippen)
+
+Bug fixes
+
+* Fix `include` matcher so that `expect({}).to include(:a => nil)`
+  fails as it should (Sam Phippen).
+* Fix `be_an_instance_of` matcher so that `Class#to_s` is used in the
+  description rather than `Class#inspect`, since some classes (like
+  `ActiveRecord::Base`) define a long, verbose `#inspect`.
+  (Tom Stuart)
+
+### 2.11.3 / 2012-09-04
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.2...v2.11.3)
+
+Bug fixes
+
+* Fix (and deprecate) `expect { }.should` syntax so that it works even
+  though it was never a documented or intended syntax. It worked as a
+  consequence of the implementation of `expect` in RSpec 2.10 and
+  earlier. (Myron Marston)
+* Ensure #== is defined on built in matchers so that they can be composed.
+  For example:
+
+    expect {
+      user.emailed!
+    }.to change { user.last_emailed_at }.to be_within(1.second).of(Time.zone.now)
+
+### 2.11.2 / 2012-07-25
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.1...v2.11.2)
+
+Bug fixes
+
+* Define `should` and `should_not` on `Object` rather than `BasicObject`
+  on MacRuby. On MacRuby, `BasicObject` is defined but is not the root
+  of the object hierarchy. (Gabriel Gilder)
+
+### 2.11.1 / 2012-07-08
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.0...v2.11.1)
+
+Bug fixes
+
+* Constrain `actual` in `be_within` matcher to values that respond to `-` instead
+  of requiring a specific type.
+    * `Time`, for example, is a legit alternative.
+
+### 2.11.0 / 2012-07-07
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.10.0...v2.11.0)
+
+Enhancements
+
+* Expand `expect` syntax so that it supports expections on bare values
+  in addition to blocks (Myron Marston).
+* Add configuration options to control available expectation syntaxes
+  (Myron Marston):
+  * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :expect }`
+  * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :should }`
+  * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }`
+  * `RSpec.configuration.add_should_and_should_not_to Delegator`
+
+Bug fixes
+
+* Allow only `Numeric` values to be the "actual" in the `be_within` matcher.
+  This prevents confusing error messages. (Su Zhang @zhangsu)
+* Define `should` and `should_not` on `BasicObject` rather than `Kernel`
+  on 1.9. This makes `should` and `should_not` work properly with
+  `BasicObject`-subclassed proxy objects like `Delegator`. (Myron
+  Marston)
+
+### 2.10.0 / 2012-05-03
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.1...v2.10.0)
+
+Enhancements
+
+* Add new `start_with` and `end_with` matchers (Jeremy Wadsack)
+* Add new matchers for specifying yields (Myron Marston):
+    * `expect {...}.to yield_control`
+    * `expect {...}.to yield_with_args(1, 2, 3)`
+    * `expect {...}.to yield_with_no_args`
+    * `expect {...}.to yield_successive_args(1, 2, 3)`
+* `match_unless_raises` takes multiple exception args
+
+Bug fixes
+
+* Fix `be_within` matcher to be inclusive of delta.
+* Fix message-specific specs to pass on Rubinius (John Firebaugh)
+
+### 2.9.1 / 2012-04-03
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...v2.9.1)
+
+Bug fixes
+
+* Provide a helpful message if the diff between two objects is empty.
+* Fix bug diffing single strings with multiline strings.
+* Fix for error with using custom matchers inside other custom matchers
+  (mirasrael)
+* Fix using execution context methods in nested DSL matchers (mirasrael)
+
+### 2.9.0 / 2012-03-17
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0...v2.9.0)
+
+Enhancements
+
+* Move built-in matcher classes to RSpec::Matchers::BuiltIn to reduce pollution
+  of RSpec::Matchers (which is included in every example).
+* Autoload files with matcher classes to improve load time.
+
+Bug fixes
+
+* Align `respond_to?` and `method_missing` in DSL-defined matchers.
+* Clear out user-defined instance variables between invocations of DSL-defined
+  matchers.
+* Dup the instance of a DSL generated matcher so its state is not changed by
+  subsequent invocations.
+* Treat expected args consistently across positive and negative expectations
+  (thanks to Ralf Kistner for the heads up)
+
+### 2.8.0 / 2012-01-04
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc2...v2.8.0)
+
+Enhancements
+
+* Better diff output for Hash (Philippe Creux)
+* Eliminate Ruby warnings (Olek Janiszewski)
+
+### 2.8.0.rc2 / 2011-12-19
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc1...v2.8.0.rc2)
+
+No changes for this release. Just releasing with the other rspec gems.
+
+### 2.8.0.rc1 / 2011-11-06
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.7.0...v2.8.0.rc1)
+
+Enhancements
+
+* Use classes for the built-in matchers (they're faster).
+* Eliminate Ruby warnings (Matijs van Zuijlen)
+
+### 2.7.0 / 2011-10-16
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.6.0...v2.7.0)
+
+Enhancements
+
+* `HaveMatcher` converts argument using `to_i` (Alex Bepple & Pat Maddox)
+* Improved failure message for the `have_xxx` matcher (Myron Marston)
+* `HaveMatcher` supports `count` (Matthew Bellantoni)
+* Change matcher dups `Enumerable` before the action, supporting custom
+  `Enumerable` types like `CollectionProxy` in Rails (David Chelimsky)
+
+Bug fixes
+
+* Fix typo in `have(n).xyz` documentation (Jean Boussier)
+* fix `safe_sort` for ruby 1.9.2 (`Kernel` now defines `<=>` for Object) (Peter
+  van Hardenberg)
+
+### 2.6.0 / 2011-05-12
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.5.0...v2.6.0)
+
+Enhancements
+
+* `change` matcher accepts regexps (Robert Davis)
+* better descriptions for `have_xxx` matchers (Magnus Bergmark)
+* `range.should cover(*values)` (Anders Furseth)
+
+Bug fixes
+
+* Removed non-ascii characters that were choking rcov (Geoffrey Byers)
+* change matcher dups arrays and hashes so their before/after states can be
+  compared correctly.
+* Fix the order of inclusion of RSpec::Matchers in Test::Unit::TestCase and
+  MiniTest::Unit::TestCase to prevent a SystemStackError (Myron Marston)
+
+### 2.5.0 / 2011-02-05
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.4.0...v2.5.0)
+
+Enhancements
+
+* `should exist` works with `exist?` or `exists?` (Myron Marston)
+* `expect { ... }.not_to do_something` (in addition to `to_not`)
+
+Documentation
+
+* improved docs for raise_error matcher (James Almond)
+
+### 2.4.0 / 2011-01-02
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.3.0...v2.4.0)
+
+No functional changes in this release, which was made to align with the
+rspec-core-2.4.0 release.
+
+Enhancements
+
+* improved RDoc for change matcher (Jo Liss)
+
+### 2.3.0 / 2010-12-12
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.2.1...v2.3.0)
+
+Enhancements
+
+* diff strings when include matcher fails (Mike Sassak)
+
+### 2.2.0 / 2010-11-28
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.1.0...v2.2.0)
+
+### 2.1.0 / 2010-11-07
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.1...v2.1.0)
+
+Enhancements
+
+* `be_within(delta).of(expected)` matcher (Myron Marston)
+* Lots of new Cucumber features (Myron Marston)
+* Raise error if you try `should != expected` on Ruby-1.9 (Myron Marston)
+* Improved failure messages from `throw_symbol` (Myron Marston)
+
+Bug fixes
+
+* Eliminate hard dependency on `RSpec::Core` (Myron Marston)
+* `have_matcher` - use pluralize only when ActiveSupport inflections are indeed
+  defined (Josep M Bach)
+* throw_symbol matcher no longer swallows exceptions (Myron Marston)
+* fix matcher chaining to avoid name collisions (Myron Marston)
+
+### 2.0.0 / 2010-10-10
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.rc...v2.0.0)
+
+Enhancements
+
+* Add match_for_should_not method to matcher DSL (Myron Marston)
+
+Bug fixes
+
+* `respond_to` matcher works correctly with `should_not` with multiple methods
+  (Myron Marston)
+* `include` matcher works correctly with `should_not` with multiple values
+  (Myron Marston)
+
+### 2.0.0.rc / 2010-10-05
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.22...v2.0.0.rc)
+
+Enhancements
+
+* `require 'rspec/expectations'` in a T::U or MiniUnit suite (Josep M. Bach)
+
+Bug fixes
+
+* change by 0 passes/fails correctly (Len Smith)
+* Add description to satisfy matcher
+
+### 2.0.0.beta.22 / 2010-09-12
+
+[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.20...v2.0.0.beta.22)
+
+Enhancements
+
+* diffing improvements
+    * diff multiline strings
+    * don't diff single line strings
+    * don't diff numbers (silly)
+    * diff regexp + multiline string
+
+Bug fixes
+    * `should[_not]` change now handles boolean values correctly
diff --git a/rspec-expectations/DEV-README.md b/rspec-expectations/DEV-README.md
new file mode 100644
index 0000000..a5696e2
--- /dev/null
+++ b/rspec-expectations/DEV-README.md
@@ -0,0 +1,28 @@
+## Set up the dev environment
+
+    git clone git://github.com/rspec/rspec-expectations.git
+    cd rspec-expectations
+    gem install bundler
+    bundle install
+
+Now you should be able to run any of:
+
+    rake
+    rake spec
+    rake cucumber
+
+Or, if you prefer to use the rspec and cucumber commands directly, you can either:
+
+    bundle exec rspec
+
+Or ...
+
+    bundle install --binstubs
+    bin/rspec
+
+## Customize the dev enviroment
+
+The Gemfile includes the gems you'll need to be able to run specs. If you want
+to customize your dev enviroment with additional tools like guard or
+ruby-debug, add any additional gem declarations to Gemfile-custom (see
+Gemfile-custom.sample for some examples).
diff --git a/rspec-expectations/Gemfile b/rspec-expectations/Gemfile
new file mode 100644
index 0000000..d2d3508
--- /dev/null
+++ b/rspec-expectations/Gemfile
@@ -0,0 +1,35 @@
+source "https://rubygems.org"
+
+gemspec
+
+branch = File.read(File.expand_path("../maintenance-branch", __FILE__)).chomp
+%w[rspec rspec-core rspec-mocks rspec-support].each do |lib|
+  library_path = File.expand_path("../../#{lib}", __FILE__)
+  if File.exist?(library_path) && !ENV['USE_GIT_REPOS']
+    gem lib, :path => library_path
+  else
+    gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => branch
+  end
+end
+
+gem 'yard', '0.8.7.4', :require => false
+
+### deps for rdoc.info
+group :documentation do
+  gem 'redcarpet',     '2.1.1',   :platform => :mri
+  gem 'github-markup', '0.7.2'
+end
+
+gem 'simplecov'
+
+platforms :jruby do
+  gem "jruby-openssl"
+end
+
+platforms :rbx do
+  gem 'rubysl'
+end
+
+gem 'rubocop', "~> 0.23.0", :platform => [:ruby_19, :ruby_20, :ruby_21]
+
+eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
diff --git a/rspec-expectations/Gemfile-custom.sample b/rspec-expectations/Gemfile-custom.sample
new file mode 100644
index 0000000..a501767
--- /dev/null
+++ b/rspec-expectations/Gemfile-custom.sample
@@ -0,0 +1,19 @@
+group :development do
+  gem 'interactive_rspec'
+  gem 'relish', '~> 0.6.0'
+  gem 'guard-rspec', '~> 1.2.1'
+  gem 'growl', '1.0.3'
+  gem 'spork', '0.9.0'
+
+  platform :mri do
+    gem 'rb-fsevent', '~> 0.9.0'
+    gem 'ruby-prof', '~> 0.10.0'
+
+    case RUBY_VERSION
+    when /^1.8/
+      gem 'ruby-debug'
+    when /^1.9/
+      gem 'debugger'
+    end
+  end
+end
diff --git a/rspec-expectations/Guardfile b/rspec-expectations/Guardfile
new file mode 100644
index 0000000..84221ba
--- /dev/null
+++ b/rspec-expectations/Guardfile
@@ -0,0 +1,6 @@
+guard 'rspec', :version => 2 do
+  watch(/^spec\/(.*)_spec.rb/)
+  watch(/^lib\/(.*)\.rb/)         { |m| "spec/#{m[1]}_spec.rb" }
+  watch(/^spec\/spec_helper.rb/)  { "spec" }
+  watch(/^lib\/rspec\/matchers\/built_in/)  { "spec" }
+end
diff --git a/License.txt b/rspec-expectations/License.txt
similarity index 95%
copy from License.txt
copy to rspec-expectations/License.txt
index 02bc06c..91cfc94 100644
--- a/License.txt
+++ b/rspec-expectations/License.txt
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2009 Chad Humphries, David Chelimsky
+Copyright (c) 2012 David Chelimsky, Myron Marston
 Copyright (c) 2006 David Chelimsky, The RSpec Development Team
 Copyright (c) 2005 Steven Baker
 
diff --git a/rspec-expectations/README.md b/rspec-expectations/README.md
new file mode 100644
index 0000000..eaaa6d2
--- /dev/null
+++ b/rspec-expectations/README.md
@@ -0,0 +1,289 @@
+# RSpec Expectations [![Build Status](https://secure.travis-ci.org/rspec/rspec-expectations.svg?branch=master)](http://travis-ci.org/rspec/rspec-expectations) [![Code Climate](https://codeclimate.com/github/rspec/rspec-expectations.svg)](https://codeclimate.com/github/rspec/rspec-expectations)
+
+RSpec::Expectations lets you express expected outcomes on an object in an
+example.
+
+    expect(account.balance).to eq(Money.new(37.42, :USD))
+
+## Install
+
+If you want to use rspec-expectations with rspec, just install the rspec gem
+and RubyGems will also install rspec-expectations for you (along with
+rspec-core and rspec-mocks):
+
+    gem install rspec
+
+Want to run against the `master` branch? You'll need to include the dependent
+RSpec repos as well. Add the following to your `Gemfile`:
+
+```ruby
+%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
+  gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => 'master'
+end
+```
+
+If you want to use rspec-expectations with another tool, like Test::Unit,
+Minitest, or Cucumber, you can install it directly:
+
+    gem install rspec-expectations
+
+## Basic usage
+
+Here's an example using rspec-core:
+
+```ruby
+RSpec.describe Order do
+  it "sums the prices of the items in its line items" do
+    order = Order.new
+    order.add_entry(LineItem.new(:item => Item.new(
+      :price => Money.new(1.11, :USD)
+    )))
+    order.add_entry(LineItem.new(:item => Item.new(
+      :price => Money.new(2.22, :USD),
+      :quantity => 2
+    )))
+    expect(order.total).to eq(Money.new(5.55, :USD))
+  end
+end
+```
+
+The `describe` and `it` methods come from rspec-core.  The `Order`, `LineItem`, `Item` and `Money` classes would be from _your_ code. The last line of the example
+expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then
+the example passes. If not, it fails with a message like:
+
+    expected: #<Money @value=5.55 @currency=:USD>
+         got: #<Money @value=1.11 @currency=:USD>
+
+## Built-in matchers
+
+### Equivalence
+
+```ruby
+expect(actual).to eq(expected)  # passes if actual == expected
+expect(actual).to eql(expected) # passes if actual.eql?(expected)
+expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected))
+```
+
+Note: The new `expect` syntax no longer supports the `==` matcher.
+
+### Identity
+
+```ruby
+expect(actual).to be(expected)    # passes if actual.equal?(expected)
+expect(actual).to equal(expected) # passes if actual.equal?(expected)
+```
+
+### Comparisons
+
+```ruby
+expect(actual).to be >  expected
+expect(actual).to be >= expected
+expect(actual).to be <= expected
+expect(actual).to be <  expected
+expect(actual).to be_within(delta).of(expected)
+```
+
+### Regular expressions
+
+```ruby
+expect(actual).to match(/expression/)
+```
+
+Note: The new `expect` syntax no longer supports the `=~` matcher.
+
+### Types/classes
+
+```ruby
+expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected
+expect(actual).to be_a(expected)              # passes if actual.is_a?(expected)
+expect(actual).to be_an(expected)             # an alias for be_a
+expect(actual).to be_a_kind_of(expected)      # another alias
+```
+
+### Truthiness
+
+```ruby
+expect(actual).to be_truthy   # passes if actual is truthy (not nil or false)
+expect(actual).to be true     # passes if actual == true
+expect(actual).to be_falsy    # passes if actual is falsy (nil or false)
+expect(actual).to be false    # passes if actual == false
+expect(actual).to be_nil      # passes if actual is nil
+expect(actual).to_not be_nil  # passes if actual is not nil
+```
+
+### Expecting errors
+
+```ruby
+expect { ... }.to raise_error
+expect { ... }.to raise_error(ErrorClass)
+expect { ... }.to raise_error("message")
+expect { ... }.to raise_error(ErrorClass, "message")
+```
+
+### Expecting throws
+
+```ruby
+expect { ... }.to throw_symbol
+expect { ... }.to throw_symbol(:symbol)
+expect { ... }.to throw_symbol(:symbol, 'value')
+```
+
+### Yielding
+
+```ruby
+expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args
+
+expect { |b| yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded
+
+expect { |b| 5.tap(&b) }.to yield_with_args(5)
+expect { |b| 5.tap(&b) }.to yield_with_args(Fixnum)
+expect { |b| "a string".tap(&b) }.to yield_with_args(/str/)
+
+expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
+expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
+```
+
+### Predicate matchers
+
+```ruby
+expect(actual).to be_xxx         # passes if actual.xxx?
+expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg)
+```
+
+### Ranges (Ruby >= 1.9 only)
+
+```ruby
+expect(1..10).to cover(3)
+```
+
+### Collection membership
+
+```ruby
+expect(actual).to include(expected)
+expect(actual).to start_with(expected)
+expect(actual).to end_with(expected)
+
+expect(actual).to contain_exactly(individual, items)
+# ...which is the same as:
+expect(actual).to match_array(expected_array)
+```
+
+#### Examples
+
+```ruby
+expect([1, 2, 3]).to include(1)
+expect([1, 2, 3]).to include(1, 2)
+expect([1, 2, 3]).to start_with(1)
+expect([1, 2, 3]).to start_with(1, 2)
+expect([1, 2, 3]).to end_with(3)
+expect([1, 2, 3]).to end_with(2, 3)
+expect({:a => 'b'}).to include(:a => 'b')
+expect("this string").to include("is str")
+expect("this string").to start_with("this")
+expect("this string").to end_with("ring")
+expect([1, 2, 3]).to contain_exactly(2, 3, 1)
+expect([1, 2, 3]).to match_array([3, 2, 1])
+```
+
+## `should` syntax
+
+In addition to the `expect` syntax, rspec-expectations continues to support the
+`should` syntax:
+
+```ruby
+actual.should eq expected
+actual.should be > 3
+[1, 2, 3].should_not include 4
+```
+
+See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/master/Should.md)
+
+## Compound Matcher Expressions
+
+You can also create compound matcher expressions using `and` or `or`:
+
+``` ruby
+expect(alphabet).to start_with("a").and end_with("z")
+expect(stoplight.color).to eq("red").or eq("green").or eq("yellow")
+```
+
+## Composing Matchers
+
+Many of the built-in matchers are designed to take matchers as
+arguments, to allow you to flexibly specify only the essential
+aspects of an object or data structure. In addition, all of the
+built-in matchers have one or more aliases that provide better
+phrasing for when they are used as arguments to another matcher.
+
+### Examples
+
+```ruby
+expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) )
+
+expect { s = "barn" }.to change { s }
+  .from( a_string_matching(/foo/) )
+  .to( a_string_matching(/bar/) )
+
+expect(["barn", 2.45]).to contain_exactly(
+  a_value_within(0.1).of(2.5),
+  a_string_starting_with("bar")
+)
+
+expect(["barn", "food", 2.45]).to end_with(
+  a_string_matching("foo"),
+  a_value > 2
+)
+
+expect(["barn", 2.45]).to include( a_string_starting_with("bar") )
+
+expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/))
+
+hash = {
+  :a => {
+    :b => ["foo", 5],
+    :c => { :d => 2.05 }
+  }
+}
+
+expect(hash).to match(
+  :a => {
+    :b => a_collection_containing_exactly(
+      a_string_starting_with("f"),
+      an_instance_of(Fixnum)
+    ),
+    :c => { :d => (a_value < 3) }
+  }
+)
+
+expect { |probe|
+  [1, 2, 3].each(&probe)
+}.to yield_successive_args( a_value < 2, 2, a_value > 2 )
+```
+
+## Usage outside rspec-core
+
+You always need to load `rspec/expectations` even if you only want to use one part of the library:
+
+```ruby
+require 'rspec/expectations'
+```
+
+Then simply include `RSpec::Matchers` in any class:
+
+```ruby
+class MyClass
+  include RSpec::Matchers
+
+  def do_something(arg)
+    expect(arg).to be > 0
+    # do other stuff
+  end
+end
+```
+
+## Also see
+
+* [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
+* [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
+* [http://github.com/rspec/rspec-mocks](http://github.com/rspec/rspec-mocks)
+* [http://github.com/rspec/rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers)
diff --git a/rspec-expectations/Rakefile b/rspec-expectations/Rakefile
new file mode 100644
index 0000000..c7d9ab6
--- /dev/null
+++ b/rspec-expectations/Rakefile
@@ -0,0 +1,78 @@
+require 'bundler'
+Bundler.setup
+Bundler::GemHelper.install_tasks
+
+require 'rake'
+require 'rspec/core/rake_task'
+require 'rspec/expectations/version'
+
+require 'cucumber/rake/task'
+Cucumber::Rake::Task.new(:cucumber)
+
+desc "Run all examples"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.ruby_opts = %w[-w]
+end
+
+with_changelog_in_features = lambda do |&block|
+  begin
+    sh "cp Changelog.md features/"
+    block.call
+  ensure
+    sh "rm features/Changelog.md"
+  end
+end
+
+desc "Push docs/cukes to relishapp using the relish-client-gem"
+task :relish, :version do |t, args|
+  raise "rake relish[VERSION]" unless args[:version]
+
+  with_changelog_in_features.call do
+    if `relish versions rspec/rspec-expectations`.split.map(&:strip).include? args[:version]
+      puts "Version #{args[:version]} already exists"
+    else
+      sh "relish versions:add rspec/rspec-expectations:#{args[:version]}"
+    end
+    sh "relish push rspec/rspec-expectations:#{args[:version]}"
+  end
+end
+
+desc "Push to relish staging environment"
+task :relish_staging do
+  with_changelog_in_features.call do
+    sh "relish push rspec-staging/rspec-expectations"
+  end
+end
+
+namespace :clobber do
+  desc "delete generated .rbc files"
+  task :rbc do
+    sh %q{find . -name "*.rbc" | xargs rm}
+  end
+end
+
+desc "delete generated files"
+task :clobber => ["clobber:rbc"] do
+  rm_rf 'doc'
+  rm_rf '.yardoc'
+  rm_rf 'pkg'
+  rm_rf 'tmp'
+  rm_rf 'coverage'
+end
+
+task :default => [:spec, :cucumber]
+
+task :verify_private_key_present do
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  unless File.exist?(private_key)
+    raise "Your private key is not present. This gem should not be built without that."
+  end
+end
+
+task :build => :verify_private_key_present
+
+require 'rubocop/rake_task'
+desc 'Run RuboCop on the lib directory'
+RuboCop::RakeTask.new(:rubocop) do |task|
+  task.patterns = ['lib/**/*.rb']
+end
diff --git a/rspec-expectations/Should.md b/rspec-expectations/Should.md
new file mode 100644
index 0000000..ec0835e
--- /dev/null
+++ b/rspec-expectations/Should.md
@@ -0,0 +1,168 @@
+#`should` and `should_not` syntax
+
+From the  beginning RSpec::Expectations provided `should` and `should_not` methods
+to define expectations on any object. In version 2.11 `expect` method was
+introduced which is now the recommended way to define expectations on an object.
+
+###Why switch over from `should` to `expect`
+
+####Fix edge case issues
+
+`should` and `should_not` work by being added to every object. However, RSpec
+does not own every object and cannot ensure they work consistently on every object.
+In particular, they can lead to surprising failures when used with BasicObject-subclassed
+proxy objects.
+
+`expect` avoids these problems altogether by not needing to be available on all objects.
+
+####Unification of block and value syntaxes
+
+Before version 2.11 `expect` was just a more readable alternative for block
+expectations. Since version 2.11 `expect` can be used for both block and value
+expectations.
+
+```ruby
+expect(actual).to eq(expected)
+expect { ... }.to raise_error(ErrorClass)
+```
+
+See
+[http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax)
+For a detailed explanation
+
+### One-liners
+
+The one-liner syntax supported by
+[rspec-core](http://rubydoc.info/gems/rspec-core)  uses `should` even when
+`config.syntax = :expect`. It reads better than the alternative, and does not
+require a global monkey patch:
+
+```ruby
+describe User do
+  it { should validate_presence_of :email }
+end
+```
+
+### Using either `expect` or `should` or both
+
+By default, both `expect` and `should` syntaxes are available. In the future,
+the default may be changed to only enable the `expect` syntax.
+
+If you want your project to only use any one of these syntaxes, you can configure
+it:
+
+```ruby
+RSpec.configure do |config|
+  config.expect_with :rspec do |c|
+    c.syntax = :expect             # disables `should`
+    # or
+    c.syntax = :should             # disables `expect`
+    # or
+    c.syntax = [:should, :expect]  # default, enables both `should` and `expect`
+  end
+end
+```
+
+See
+[RSpec::Expectations::Syntax#expect](http://rubydoc.info/gems/rspec-expectations/RSpec/Expectations/Syntax:expect)
+for more information.
+
+## Usage
+
+The `should` and `should_not` methods can be used to define expectations on any
+object. 
+
+```ruby
+actual.should eq expected
+actual.should be > 3
+[1, 2, 3].should_not include 4
+```
+
+## Using Built-in matchers
+
+### Equivalence
+
+```ruby
+actual.should     eq(expected)  # passes if actual == expected
+actual.should     == expected   # passes if actual == expected
+actual.should_not eql(expected) # passes if actual.eql?(expected)
+```
+
+Note: we recommend the `eq` matcher over `==` to avoid Ruby's "== in a
+useless context" warning when the `==` matcher is used anywhere but the
+last statement of an example.
+
+### Identity
+
+```ruby
+actual.should     be(expected)    # passes if actual.equal?(expected)
+actual.should_not equal(expected) # passes if actual.equal?(expected)
+```
+
+### Comparisons
+
+```ruby
+actual.should be >  expected
+actual.should be >= expected
+actual.should be <= expected
+actual.should be <  expected
+actual.should be_within(delta).of(expected)
+```
+
+### Regular expressions
+
+```ruby
+actual.should match(/expression/)
+actual.should =~ /expression/
+```
+
+### Types/classes
+
+```ruby
+actual.should     be_an_instance_of(expected)
+actual.should_not be_a_kind_of(expected)
+```
+
+### Truthiness
+
+```ruby
+actual.should be_true  # passes if actual is truthy (not nil or false)
+actual.should be_false # passes if actual is falsy (nil or false)
+actual.should be_nil   # passes if actual is nil
+```
+
+### Predicate matchers
+
+```ruby
+actual.should     be_xxx         # passes if actual.xxx?
+actual.should_not have_xxx(:arg) # passes if actual.has_xxx?(:arg)
+```
+
+### Ranges (Ruby >= 1.9 only)
+
+```ruby
+(1..10).should cover(3)
+```
+
+### Collection membership
+
+```ruby
+actual.should include(expected)
+actual.should start_with(expected)
+actual.should end_with(expected)
+```
+
+#### Examples
+
+```ruby
+[1,2,3].should       include(1)
+[1,2,3].should       include(1, 2)
+[1,2,3].should       start_with(1)
+[1,2,3].should       start_with(1,2)
+[1,2,3].should       end_with(3)
+[1,2,3].should       end_with(2,3)
+{:a => 'b'}.should   include(:a => 'b')
+"this string".should include("is str")
+"this string".should start_with("this")
+"this string".should end_with("ring")
+```
diff --git a/rspec-expectations/appveyor.yml b/rspec-expectations/appveyor.yml
new file mode 100644
index 0000000..9e4f457
--- /dev/null
+++ b/rspec-expectations/appveyor.yml
@@ -0,0 +1,34 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+version: "{build}"
+
+# This will build all PRs targetting matching branches.
+# Without this, each PR builds twice -- once for the PR branch HEAD,
+# and once for the merge commit that github creates for each mergable PR.
+branches:
+  only:
+    - master
+    - /.*-maintenance$/
+
+# Disable normal Windows builds in favor of our test script.
+build: off
+
+install:
+  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
+  - ruby --version
+  - gem --version
+  # We lock to 1.7.7 to avoid warnings from 1.7.8
+  - gem install bundler -v=1.7.7
+  - bundler --version
+  - bundle install
+  - cinst ansicon
+
+test_script:
+  - bundle exec rspec
+
+environment:
+  matrix:
+    # ruby_version: '20' doesn't work for some reason
+    - ruby_version: '193'
+    - ruby_version: '21'
diff --git a/rspec-expectations/benchmarks/2.x_vs_3.x_matcher_dsl_implementation.rb b/rspec-expectations/benchmarks/2.x_vs_3.x_matcher_dsl_implementation.rb
new file mode 100644
index 0000000..b364b85
--- /dev/null
+++ b/rspec-expectations/benchmarks/2.x_vs_3.x_matcher_dsl_implementation.rb
@@ -0,0 +1,253 @@
+$LOAD_PATH.unshift "./lib"
+require 'benchmark'
+require 'rspec/expectations'
+
+include RSpec::Expectations
+include RSpec::Matchers
+
+n = 1000
+
+puts "3 runs of #{n} times for each example running rspec-expectations #{RSpec::Expectations::Version::STRING} -- #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+puts "Defining a custom matcher"
+Benchmark.benchmark do |bm|
+  3.times do |i|
+    bm.report do
+      n.times do |j|
+        RSpec::Matchers.define :"define_matcher_#{i}_#{j}" do
+          match { }
+        end
+      end
+    end
+  end
+end
+
+puts "Getting an instance of a custom matcher"
+RSpec::Matchers.define :be_a_multiple_of do |x|
+  match { |actual| (actual % x).zero? }
+end
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do |i|
+        be_a_multiple_of(i)
+      end
+    end
+  end
+end
+
+puts "Using a previously gotten custom matcher instance -- positive match"
+Benchmark.benchmark do |bm|
+  1.upto(3) do |i|
+    matcher = be_a_multiple_of(i)
+    bm.report do
+      n.times do |j|
+        expect(i * j).to matcher
+      end
+    end
+  end
+end
+
+puts "Using a previously gotten custom matcher instance -- negative match"
+Benchmark.benchmark do |bm|
+  2.upto(4) do |i|
+    matcher = be_a_multiple_of(i)
+    bm.report do
+      n.times do |j|
+        begin
+          expect(1 + i * j).to matcher
+        rescue RSpec::Expectations::ExpectationNotMetError
+        end
+      end
+    end
+  end
+end
+
+=begin
+
+Results are below for:
+
+- MRI 2.0.0, MRI 1.9.3, JRuby 1.7.4
+- Against 2.14.3, 3.0.0.pre before matcher DSL rewrite, 3.0.0.pre after matcher DSL rewrite
+
+Conclusions:
+
+* Getting an instance of a custom matcher was insanely slow in 2.x,
+  and it looks like the `making_declared_methods_public` hack for 1.8.6
+  was the primary source of that. Without that, getting an instance of
+  a matcher is ~20x faster. To see what changed between 2.14.3 and
+  the commit used for this benchmark, go to:
+  https://github.com/rspec/rspec-expectations/compare/v2.14.3...4c47e4c43ee6961c755d325e73181b1f5b6bf097#diff-a51020971ade2c87f1d5b93f20d711c7L6
+* With our new custom matcher DSL, using a matcher is approximately
+  the same perf. However, defining a matcher is a little bit faster,
+  and getting an instance of an already defined matcher is about 10x faster.
+
+Overall, this is definitely a net win.
+
+Results:
+
+3 runs of 1000 times for each example running rspec-expectations 2.14.3 -- ruby/2.0.0
+Defining a custom matcher
+   0.010000   0.000000   0.010000 (  0.004612)
+   0.000000   0.000000   0.000000 (  0.004674)
+   0.000000   0.000000   0.000000 (  0.004944)
+Getting an instance of a custom matcher
+   1.470000   0.010000   1.480000 (  1.472602)
+   1.420000   0.000000   1.420000 (  1.426760)
+   1.440000   0.000000   1.440000 (  1.442283)
+Using a previously gotten custom matcher instance -- positive match
+   0.000000   0.000000   0.000000 (  0.002213)
+   0.000000   0.000000   0.000000 (  0.002019)
+   0.000000   0.000000   0.000000 (  0.001884)
+Using a previously gotten custom matcher instance -- negative match
+   0.020000   0.000000   0.020000 (  0.019378)
+   0.030000   0.000000   0.030000 (  0.027001)
+   0.020000   0.010000   0.030000 (  0.022310)
+
+3 runs of 1000 times for each example running rspec-expectations 2.14.3 -- ruby/1.9.3
+Defining a custom matcher
+    0.000000   0.000000   0.000000 (  0.004455)
+   0.010000   0.000000   0.010000 (  0.004849)
+   0.010000   0.000000   0.010000 (  0.010495)
+Getting an instance of a custom matcher
+    1.690000   0.010000   1.700000 (  1.696415)
+   1.550000   0.000000   1.550000 (  1.556858)
+   1.550000   0.000000   1.550000 (  1.554830)
+Using a previously gotten custom matcher instance -- positive match
+    0.000000   0.000000   0.000000 (  0.002161)
+   0.000000   0.000000   0.000000 (  0.002038)
+   0.010000   0.000000   0.010000 (  0.002091)
+Using a previously gotten custom matcher instance -- negative match
+    0.050000   0.010000   0.060000 (  0.060512)
+   0.050000   0.000000   0.050000 (  0.064532)
+   0.060000   0.010000   0.070000 (  0.062206)
+
+3 runs of 1000 times for each example running rspec-expectations 2.14.3 -- jruby/1.9.3
+Defining a custom matcher
+    0.660000   0.010000   0.670000 (  0.299000)
+   0.280000   0.000000   0.280000 (  0.178000)
+   0.220000   0.010000   0.230000 (  0.143000)
+Getting an instance of a custom matcher
+    1.970000   0.030000   2.000000 (  1.389000)
+   1.340000   0.030000   1.370000 (  0.907000)
+   0.820000   0.030000   0.850000 (  0.795000)
+Using a previously gotten custom matcher instance -- positive match
+    0.110000   0.000000   0.110000 (  0.058000)
+   0.050000   0.000000   0.050000 (  0.036000)
+   0.030000   0.000000   0.030000 (  0.030000)
+Using a previously gotten custom matcher instance -- negative match
+    0.930000   0.010000   0.940000 (  0.474000)
+   0.620000   0.000000   0.620000 (  0.376000)
+   0.390000   0.000000   0.390000 (  0.279000)
+
+3 runs of 1000 times for each example running rspec-expectations 3.0.0.pre (before DSL rewrite) -- ruby/2.0.0
+Defining a custom matcher
+   0.010000   0.000000   0.010000 (  0.004719)
+   0.000000   0.000000   0.000000 (  0.004424)
+   0.010000   0.000000   0.010000 (  0.005562)
+Getting an instance of a custom matcher
+   0.050000   0.000000   0.050000 (  0.059949)
+   0.060000   0.000000   0.060000 (  0.058208)
+   0.060000   0.010000   0.070000 (  0.067402)
+Using a previously gotten custom matcher instance -- positive match
+   0.010000   0.000000   0.010000 (  0.001696)
+   0.000000   0.000000   0.000000 (  0.001558)
+   0.000000   0.000000   0.000000 (  0.001488)
+Using a previously gotten custom matcher instance -- negative match
+   0.020000   0.000000   0.020000 (  0.021522)
+   0.030000   0.000000   0.030000 (  0.027728)
+   0.020000   0.000000   0.020000 (  0.026185)
+
+3 runs of 1000 times for each example running rspec-expectations 3.0.0.pre (before DSL rewrite) -- ruby/1.9.3
+Defining a custom matcher
+    0.010000   0.000000   0.010000 (  0.004650)
+   0.000000   0.000000   0.000000 (  0.004658)
+   0.010000   0.000000   0.010000 (  0.011111)
+Getting an instance of a custom matcher
+    0.050000   0.010000   0.060000 (  0.047230)
+   0.060000   0.000000   0.060000 (  0.065500)
+   0.070000   0.000000   0.070000 (  0.073099)
+Using a previously gotten custom matcher instance -- positive match
+    0.000000   0.000000   0.000000 (  0.002007)
+   0.000000   0.000000   0.000000 (  0.002370)
+   0.010000   0.000000   0.010000 (  0.002121)
+Using a previously gotten custom matcher instance -- negative match
+    0.070000   0.010000   0.080000 (  0.078960)
+   0.060000   0.000000   0.060000 (  0.061351)
+   0.060000   0.000000   0.060000 (  0.069949)
+
+3 runs of 1000 times for each example running rspec-expectations 3.0.0.pre (before DSL rewrite) -- jruby/1.9.3
+Defining a custom matcher
+    0.730000   0.010000   0.740000 (  0.303000)
+   0.240000   0.010000   0.250000 (  0.153000)
+   0.210000   0.000000   0.210000 (  0.140000)
+Getting an instance of a custom matcher
+    0.940000   0.010000   0.950000 (  0.538000)
+   0.510000   0.000000   0.510000 (  0.174000)
+   0.160000   0.000000   0.160000 (  0.090000)
+Using a previously gotten custom matcher instance -- positive match
+    0.120000   0.000000   0.120000 (  0.053000)
+   0.040000   0.000000   0.040000 (  0.025000)
+   0.030000   0.000000   0.030000 (  0.026000)
+Using a previously gotten custom matcher instance -- negative match
+    0.970000   0.010000   0.980000 (  0.458000)
+   0.480000   0.010000   0.490000 (  0.314000)
+   0.360000   0.000000   0.360000 (  0.269000)
+
+3 runs of 1000 times for each example running rspec-expectations 3.0.0.pre -- ruby/2.0.0
+Defining a custom matcher
+   0.000000   0.000000   0.000000 (  0.003138)
+   0.000000   0.000000   0.000000 (  0.003083)
+   0.010000   0.000000   0.010000 (  0.003448)
+Getting an instance of a custom matcher
+   0.000000   0.000000   0.000000 (  0.007273)
+   0.010000   0.000000   0.010000 (  0.007096)
+   0.020000   0.000000   0.020000 (  0.021662)
+Using a previously gotten custom matcher instance -- positive match
+   0.000000   0.000000   0.000000 (  0.002582)
+   0.000000   0.000000   0.000000 (  0.001832)
+   0.010000   0.000000   0.010000 (  0.001588)
+Using a previously gotten custom matcher instance -- negative match
+   0.010000   0.000000   0.010000 (  0.017756)
+   0.030000   0.000000   0.030000 (  0.021225)
+   0.020000   0.010000   0.030000 (  0.021281)
+
+3 runs of 1000 times for each example running rspec-expectations 3.0.0.pre -- ruby/1.9.3
+Defining a custom matcher
+    0.000000   0.000000   0.000000 (  0.002903)
+   0.000000   0.000000   0.000000 (  0.002919)
+   0.010000   0.000000   0.010000 (  0.008956)
+Getting an instance of a custom matcher
+    0.010000   0.000000   0.010000 (  0.006640)
+   0.000000   0.000000   0.000000 (  0.006557)
+   0.010000   0.000000   0.010000 (  0.007869)
+Using a previously gotten custom matcher instance -- positive match
+    0.010000   0.000000   0.010000 (  0.003332)
+   0.000000   0.000000   0.000000 (  0.003288)
+   0.000000   0.000000   0.000000 (  0.002769)
+Using a previously gotten custom matcher instance -- negative match
+    0.070000   0.010000   0.080000 (  0.075547)
+   0.050000   0.000000   0.050000 (  0.053149)
+   0.060000   0.010000   0.070000 (  0.062583)
+
+3 runs of 1000 times for each example running rspec-expectations 3.0.0.pre -- jruby/1.9.3
+Defining a custom matcher
+    0.780000   0.020000   0.800000 (  0.316000)
+   0.170000   0.010000   0.180000 (  0.139000)
+   0.220000   0.000000   0.220000 (  0.135000)
+Getting an instance of a custom matcher
+    0.340000   0.000000   0.340000 (  0.183000)
+   0.230000   0.010000   0.240000 (  0.131000)
+   0.180000   0.000000   0.180000 (  0.104000)
+Using a previously gotten custom matcher instance -- positive match
+    0.170000   0.000000   0.170000 (  0.076000)
+   0.070000   0.000000   0.070000 (  0.049000)
+   0.110000   0.000000   0.110000 (  0.047000)
+Using a previously gotten custom matcher instance -- negative match
+    0.970000   0.010000   0.980000 (  0.461000)
+   0.410000   0.000000   0.410000 (  0.316000)
+   0.350000   0.010000   0.360000 (  0.256000)
+
+=end
+
diff --git a/rspec-expectations/benchmarks/autoload_v_require.rb b/rspec-expectations/benchmarks/autoload_v_require.rb
new file mode 100644
index 0000000..4258df3
--- /dev/null
+++ b/rspec-expectations/benchmarks/autoload_v_require.rb
@@ -0,0 +1,25 @@
+require 'benchmark'
+
+n = 10
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        `bin/rspec benchmarks/example_spec.rb`
+      end
+    end
+  end
+end
+
+# Before autoloading matcher class files
+#    0.000000   0.010000   8.800000 (  8.906383)
+#    0.010000   0.010000   8.880000 (  8.980907)
+#    0.000000   0.010000   8.820000 (  8.918083)
+#
+# After autoloading matcher class files
+#    0.000000   0.010000   8.610000 (  8.701434)
+#    0.010000   0.010000   8.620000 (  8.741811)
+#    0.000000   0.000000   8.580000 (  8.677235)
+#
+# Roughly 2.5% improvement in load time (every bit counts!)
diff --git a/rspec-expectations/benchmarks/cloning_matchers.rb b/rspec-expectations/benchmarks/cloning_matchers.rb
new file mode 100644
index 0000000..ceffcfe
--- /dev/null
+++ b/rspec-expectations/benchmarks/cloning_matchers.rb
@@ -0,0 +1,19 @@
+require 'benchmark'
+require 'rspec/expectations'
+include RSpec::Matchers
+
+n = 1_000_000
+matcher = eq(3)
+
+Benchmark.bm do |x|
+  x.report do
+    n.times { matcher.clone }
+  end
+end
+
+__END__
+
+We can do about 1000 clones per ms:
+
+      user     system      total        real
+  1.080000   0.030000   1.110000 (  1.120009)
diff --git a/rspec-expectations/benchmarks/default_messages_as_methods_v_blocks.rb b/rspec-expectations/benchmarks/default_messages_as_methods_v_blocks.rb
new file mode 100644
index 0000000..4e5d182
--- /dev/null
+++ b/rspec-expectations/benchmarks/default_messages_as_methods_v_blocks.rb
@@ -0,0 +1,27 @@
+require 'benchmark'
+require 'rspec/expectations'
+
+include RSpec::Expectations
+include RSpec::Matchers
+
+RSpec::Matchers.define :eq_using_dsl do |expected|
+  match do |actual|
+    actual == expected
+  end
+end
+
+n = 10000
+
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        eq_using_dsl(5).tap do |m|
+          m.description
+          m.failure_message_for_should
+          m.failure_message_for_should_not
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/benchmarks/example_spec.rb b/rspec-expectations/benchmarks/example_spec.rb
new file mode 100644
index 0000000..c32364d
--- /dev/null
+++ b/rspec-expectations/benchmarks/example_spec.rb
@@ -0,0 +1,9 @@
+describe "something" do
+  it "does something that passes" do
+    1.should eq(1)
+  end
+
+  it "does something that fails" do
+    1.should eq(2)
+  end
+end
diff --git a/rspec-expectations/benchmarks/include_v_superclass.rb b/rspec-expectations/benchmarks/include_v_superclass.rb
new file mode 100644
index 0000000..a3137a9
--- /dev/null
+++ b/rspec-expectations/benchmarks/include_v_superclass.rb
@@ -0,0 +1,39 @@
+require 'benchmark'
+
+n = 10_000
+
+class  Foo; end
+module Bar; end
+
+
+Benchmark.benchmark do |bm|
+  puts "Class.new(Foo)"
+
+  3.times do
+    bm.report do
+      n.times do
+        Class.new(Foo)
+      end
+    end
+  end
+
+  puts "Class.new { include Bar }"
+
+  3.times do
+    bm.report do
+      n.times do
+        Class.new { include Bar }
+      end
+    end
+  end
+end
+
+# $ ruby benchmarks/include_v_superclass.rb
+# Class.new(Foo)
+#   0.030000   0.000000   0.030000 (  0.033536)
+#   0.020000   0.000000   0.020000 (  0.022077)
+#   0.040000   0.010000   0.050000 (  0.035813)
+# Class.new { include Bar }
+#   0.040000   0.000000   0.040000 (  0.041427)
+#   0.040000   0.000000   0.040000 (  0.039019)
+#   0.030000   0.000000   0.030000 (  0.037018)
diff --git a/rspec-expectations/benchmarks/match_array/failing_with_distinct_items.rb b/rspec-expectations/benchmarks/match_array/failing_with_distinct_items.rb
new file mode 100644
index 0000000..dcd79c2
--- /dev/null
+++ b/rspec-expectations/benchmarks/match_array/failing_with_distinct_items.rb
@@ -0,0 +1,147 @@
+$LOAD_PATH.unshift "./lib"
+require 'benchmark'
+require 'rspec/expectations'
+require 'securerandom'
+
+extend RSpec::Matchers
+
+sizes = [10, 100, 1000, 2000, 4000]
+
+puts "rspec-expectations #{RSpec::Expectations::Version::STRING} -- #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+puts
+puts "Failing `match_array` expectation with lists of distinct strings having 1 unmatched pair"
+puts
+
+Benchmark.benchmark do |bm|
+  sizes.each do |size|
+    actual = Array.new(size) { SecureRandom.uuid }
+
+    expecteds = Array.new(3) do
+      array = actual.shuffle
+      # replace one entry with a different value
+      array[rand(array.length)] = SecureRandom.uuid
+      array
+    end
+
+    expecteds.each do |expected|
+      bm.report("#{size.to_s.rjust(5)} items") do
+        begin
+          expect(actual).to match_array(expected)
+        rescue RSpec::Expectations::ExpectationNotMetError
+        else
+          raise "did not fail but should have"
+        end
+      end
+    end
+  end
+end
+
+__END__
+
+Before new composable matchers algo:
+
+   10 items  0.000000   0.000000   0.000000 (  0.000813)
+   10 items  0.000000   0.000000   0.000000 (  0.000099)
+   10 items  0.000000   0.000000   0.000000 (  0.000127)
+  100 items  0.000000   0.000000   0.000000 (  0.000707)
+  100 items  0.000000   0.000000   0.000000 (  0.000612)
+  100 items  0.000000   0.000000   0.000000 (  0.000600)
+ 1000 items  0.040000   0.000000   0.040000 (  0.038679)
+ 1000 items  0.040000   0.000000   0.040000 (  0.041379)
+ 1000 items  0.040000   0.000000   0.040000 (  0.036680)
+ 2000 items  0.130000   0.000000   0.130000 (  0.131681)
+ 2000 items  0.120000   0.000000   0.120000 (  0.123664)
+ 2000 items  0.130000   0.000000   0.130000 (  0.128799)
+ 4000 items  0.490000   0.000000   0.490000 (  0.489446)
+ 4000 items  0.510000   0.000000   0.510000 (  0.511915)
+ 4000 items  0.480000   0.010000   0.490000 (  0.477616)
+
+After:
+
+   10 items  0.000000   0.000000   0.000000 (  0.001382)
+   10 items  0.000000   0.000000   0.000000 (  0.000156)
+   10 items  0.000000   0.000000   0.000000 (  0.000161)
+  100 items  0.010000   0.000000   0.010000 (  0.005052)
+  100 items  0.000000   0.000000   0.000000 (  0.004991)
+  100 items  0.010000   0.000000   0.010000 (  0.004984)
+ 1000 items  0.470000   0.000000   0.470000 (  0.470043)
+ 1000 items  0.500000   0.000000   0.500000 (  0.499316)
+ 1000 items  0.490000   0.000000   0.490000 (  0.488582)
+ 2000 items  1.910000   0.000000   1.910000 (  1.917279)
+ 2000 items  1.930000   0.010000   1.940000 (  1.931002)
+ 2000 items  1.920000   0.000000   1.920000 (  1.928989)
+ 4000 items  7.860000   0.010000   7.870000 (  7.881995)
+ 4000 items  7.980000   0.010000   7.990000 (  8.003643)
+ 4000 items  8.000000   0.010000   8.010000 (  8.031382)
+
+With "smaller subproblem" optimization: (about 25% slower)
+
+   10 items  0.010000   0.000000   0.010000 (  0.001331)
+   10 items  0.000000   0.000000   0.000000 (  0.000175)
+   10 items  0.000000   0.000000   0.000000 (  0.000165)
+  100 items  0.000000   0.000000   0.000000 (  0.006137)
+  100 items  0.010000   0.000000   0.010000 (  0.005880)
+  100 items  0.000000   0.000000   0.000000 (  0.005950)
+ 1000 items  0.630000   0.000000   0.630000 (  0.634294)
+ 1000 items  0.620000   0.000000   0.620000 (  0.622427)
+ 1000 items  0.640000   0.000000   0.640000 (  0.641505)
+ 2000 items  2.420000   0.000000   2.420000 (  2.419876)
+ 2000 items  2.430000   0.000000   2.430000 (  2.442544)
+ 2000 items  2.380000   0.010000   2.390000 (  2.385106)
+ 4000 items  9.780000   0.010000   9.790000 (  9.811499)
+ 4000 items  9.670000   0.010000   9.680000 (  9.688799)
+ 4000 items  9.710000   0.010000   9.720000 (  9.743054)
+
+With "implement `values_match?` ourselves" optimization: (more than twice as fast!)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001189)
+   10 items  0.000000   0.000000   0.000000 (  0.000149)
+   10 items  0.000000   0.000000   0.000000 (  0.000130)
+  100 items  0.000000   0.000000   0.000000 (  0.002927)
+  100 items  0.000000   0.000000   0.000000 (  0.002856)
+  100 items  0.010000   0.000000   0.010000 (  0.003028)
+ 1000 items  0.250000   0.000000   0.250000 (  0.245146)
+ 1000 items  0.240000   0.000000   0.240000 (  0.246291)
+ 1000 items  0.320000   0.000000   0.320000 (  0.315192)
+ 2000 items  1.120000   0.000000   1.120000 (  1.128162)
+ 2000 items  1.030000   0.000000   1.030000 (  1.034982)
+ 2000 items  1.060000   0.000000   1.060000 (  1.063870)
+ 4000 items  4.530000   0.000000   4.530000 (  4.556346)
+ 4000 items  4.400000   0.010000   4.410000 (  4.414447)
+ 4000 items  4.410000   0.000000   4.410000 (  4.417440)
+
+With e === a || a == e || values_match?(e,a)
+   10 items  0.000000   0.000000   0.000000 (  0.001466)
+   10 items  0.000000   0.000000   0.000000 (  0.000258)
+   10 items  0.000000   0.000000   0.000000 (  0.000251)
+  100 items  0.020000   0.000000   0.020000 (  0.012369)
+  100 items  0.010000   0.000000   0.010000 (  0.012345)
+  100 items  0.010000   0.000000   0.010000 (  0.012744)
+ 1000 items  1.180000   0.000000   1.180000 (  1.187754)
+ 1000 items  1.200000   0.000000   1.200000 (  1.198681)
+ 1000 items  1.210000   0.000000   1.210000 (  1.210159)
+ 2000 items  4.760000   0.000000   4.760000 (  4.764911)
+ 2000 items  4.760000   0.000000   4.760000 (  4.757022)
+ 2000 items  4.760000   0.000000   4.760000 (  4.771776)
+ 4000 items 19.070000   0.010000  19.080000 ( 19.077930)
+ 4000 items 19.090000   0.010000  19.100000 ( 19.104171)
+ 4000 items 19.260000   0.010000  19.270000 ( 19.289653)
+
+With values_match?(e,a)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001462)
+   10 items  0.000000   0.000000   0.000000 (  0.000253)
+   10 items  0.000000   0.000000   0.000000 (  0.000244)
+  100 items  0.010000   0.000000   0.010000 (  0.011913)
+  100 items  0.010000   0.000000   0.010000 (  0.011858)
+  100 items  0.020000   0.000000   0.020000 (  0.011992)
+ 1000 items  1.210000   0.000000   1.210000 (  1.226960)
+ 1000 items  1.140000   0.000000   1.140000 (  1.147002)
+ 1000 items  1.180000   0.000000   1.180000 (  1.194010)
+ 2000 items  4.690000   0.010000   4.700000 (  4.740503)
+ 2000 items  4.680000   0.000000   4.680000 (  4.676084)
+ 2000 items  4.570000   0.000000   4.570000 (  4.581262)
+ 4000 items 18.450000   0.010000  18.460000 ( 18.532578)
+ 4000 items 18.400000   0.010000  18.410000 ( 18.520454)
+ 4000 items 18.490000   0.020000  18.510000 ( 18.592491)
diff --git a/rspec-expectations/benchmarks/match_array/failing_with_duplicate_items.rb b/rspec-expectations/benchmarks/match_array/failing_with_duplicate_items.rb
new file mode 100644
index 0000000..1e4ee98
--- /dev/null
+++ b/rspec-expectations/benchmarks/match_array/failing_with_duplicate_items.rb
@@ -0,0 +1,122 @@
+$LOAD_PATH.unshift "./lib"
+require 'benchmark'
+require 'rspec/expectations'
+
+extend RSpec::Matchers
+
+sizes = [10, 100, 1000]
+
+puts "rspec-expectations #{RSpec::Expectations::Version::STRING} -- #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+puts
+puts "Failing `match_array` expectation with lists of integers (w/dups) having 1 unmatched pair"
+puts
+
+Benchmark.benchmark do |bm|
+  sizes.each do |size|
+    actual    = Array.new(size) { rand(size / 2) }
+    expecteds = Array.new(3) do
+      array = actual.shuffle
+      array[rand(array.length)] = 9999999
+      array
+    end
+
+    expecteds.each do |expected|
+      bm.report("#{size.to_s.rjust(5)} items") do
+        begin
+          expect(actual).to match_array(expected)
+        rescue RSpec::Expectations::ExpectationNotMetError
+        else
+          raise "did not fail but should have"
+        end
+      end
+    end
+  end
+end
+
+__END__
+
+Before new composable matchers algo:
+
+   10 items  0.000000   0.000000   0.000000 (  0.000711)
+   10 items  0.000000   0.000000   0.000000 (  0.000079)
+   10 items  0.000000   0.000000   0.000000 (  0.000080)
+   20 items  0.000000   0.000000   0.000000 (  0.000105)
+   20 items  0.000000   0.000000   0.000000 (  0.000122)
+   20 items  0.000000   0.000000   0.000000 (  0.000101)
+   25 items  0.000000   0.000000   0.000000 (  0.000125)
+   25 items  0.000000   0.000000   0.000000 (  0.000137)
+   25 items  0.000000   0.000000   0.000000 (  0.000116)
+
+After:
+
+  This varies widly based on the inputs. One run:
+
+     10 items  0.010000   0.000000   0.010000 (  0.005884)
+     10 items  0.000000   0.000000   0.000000 (  0.004429)
+     10 items  0.000000   0.000000   0.000000 (  0.004733)
+     20 items  2.040000   0.000000   2.040000 (  2.049461)
+     20 items  2.080000   0.010000   2.090000 (  2.087983)
+     20 items  1.950000   0.000000   1.950000 (  1.950013)
+     25 items 10.240000   0.020000  10.260000 ( 10.280575)
+     25 items 10.390000   0.010000  10.400000 ( 10.433754)
+     25 items 10.250000   0.020000  10.270000 ( 10.311604)
+
+  Another run:
+
+     10 items  0.010000   0.010000   0.020000 (  0.015355)
+     10 items  0.010000   0.000000   0.010000 (  0.010347)
+     10 items  0.020000   0.000000   0.020000 (  0.013657)
+     20 items 36.140000   0.030000  36.170000 ( 36.236651)
+     20 items 36.010000   0.040000  36.050000 ( 36.098006)
+     20 items 35.990000   0.030000  36.020000 ( 36.071397)
+
+  (I lost patience and didn't wait for it to finish 25 items...)
+
+With "smaller subproblem" optimization: (way faster!)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001411)
+   10 items  0.000000   0.000000   0.000000 (  0.000615)
+   10 items  0.000000   0.000000   0.000000 (  0.000413)
+   20 items  0.000000   0.000000   0.000000 (  0.000947)
+   20 items  0.000000   0.000000   0.000000 (  0.001725)
+   20 items  0.000000   0.000000   0.000000 (  0.001345)
+   25 items  0.010000   0.000000   0.010000 (  0.002348)
+   25 items  0.000000   0.000000   0.000000 (  0.002836)
+   25 items  0.000000   0.000000   0.000000 (  0.002721)
+
+With "implement `values_match?` ourselves" optimization: (about twice as fast!)
+
+   10 items  0.000000   0.000000   0.000000 (  0.002450)
+   10 items  0.000000   0.000000   0.000000 (  0.000857)
+   10 items  0.000000   0.000000   0.000000 (  0.000883)
+  100 items  0.040000   0.000000   0.040000 (  0.043661)
+  100 items  0.060000   0.000000   0.060000 (  0.053046)
+  100 items  0.040000   0.010000   0.050000 (  0.051760)
+ 1000 items  3.620000   0.060000   3.680000 (  3.688289)
+ 1000 items  2.600000   0.020000   2.620000 (  2.628405)
+ 1000 items  4.660000   0.040000   4.700000 (  4.712196)
+
+With e === a || a == e || values_match?(e,a)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001992)
+   10 items  0.000000   0.000000   0.000000 (  0.000821)
+   10 items  0.000000   0.000000   0.000000 (  0.000794)
+  100 items  0.060000   0.000000   0.060000 (  0.068597)
+  100 items  0.060000   0.000000   0.060000 (  0.056409)
+  100 items  0.070000   0.010000   0.080000 (  0.072950)
+ 1000 items  4.090000   0.100000   4.190000 (  4.218107)
+ 1000 items  3.000000   0.050000   3.050000 (  3.070019)
+ 1000 items  6.040000   0.070000   6.110000 (  6.102311)
+
+With values_match?(e,a)
+
+   10 items  0.000000   0.000000   0.000000 (  0.002177)
+   10 items  0.000000   0.000000   0.000000 (  0.001201)
+   10 items  0.000000   0.000000   0.000000 (  0.000928)
+  100 items  0.050000   0.000000   0.050000 (  0.051785)
+  100 items  0.040000   0.000000   0.040000 (  0.032323)
+  100 items  0.040000   0.000000   0.040000 (  0.046934)
+ 1000 items  4.050000   0.100000   4.150000 (  4.175914)
+ 1000 items  3.040000   0.050000   3.090000 (  3.130656)
+ 1000 items  4.110000   0.050000   4.160000 (  4.161170)
diff --git a/rspec-expectations/benchmarks/match_array/passing_with_distinct_items.rb b/rspec-expectations/benchmarks/match_array/passing_with_distinct_items.rb
new file mode 100644
index 0000000..0dd1d73
--- /dev/null
+++ b/rspec-expectations/benchmarks/match_array/passing_with_distinct_items.rb
@@ -0,0 +1,154 @@
+$LOAD_PATH.unshift "./lib"
+require 'benchmark'
+require 'rspec/expectations'
+require 'securerandom'
+
+extend RSpec::Matchers
+
+sizes = [10, 100, 1000, 2000, 4000]
+
+puts "rspec-expectations #{RSpec::Expectations::Version::STRING} -- #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+puts
+puts "Passing `match_array` expectation with lists of distinct strings"
+puts
+
+Benchmark.benchmark do |bm|
+  sizes.each do |size|
+    actual    = Array.new(size) { SecureRandom.uuid }
+    expecteds = Array.new(3)    { actual.shuffle }
+    expecteds.each do |expected|
+      bm.report("#{size.to_s.rjust(5)} items") do
+        expect(actual).to match_array(expected)
+      end
+    end
+  end
+end
+
+__END__
+
+Before new composable matchers algo:
+
+   10 items  0.000000   0.000000   0.000000 (  0.000857)
+   10 items  0.000000   0.000000   0.000000 (  0.000029)
+   10 items  0.000000   0.000000   0.000000 (  0.000018)
+  100 items  0.000000   0.000000   0.000000 (  0.000334)
+  100 items  0.000000   0.000000   0.000000 (  0.000372)
+  100 items  0.000000   0.000000   0.000000 (  0.000331)
+ 1000 items  0.030000   0.000000   0.030000 (  0.029778)
+ 1000 items  0.030000   0.000000   0.030000 (  0.030566)
+ 1000 items  0.030000   0.000000   0.030000 (  0.033150)
+ 2000 items  0.140000   0.000000   0.140000 (  0.141719)
+ 2000 items  0.120000   0.000000   0.120000 (  0.124348)
+ 2000 items  0.120000   0.000000   0.120000 (  0.121202)
+ 4000 items  0.490000   0.000000   0.490000 (  0.500631)
+ 4000 items  0.470000   0.000000   0.470000 (  0.468477)
+ 4000 items  0.490000   0.010000   0.500000 (  0.492957)
+
+After:
+
+   10 items  0.000000   0.000000   0.000000 (  0.001165)
+   10 items  0.000000   0.000000   0.000000 (  0.000131)
+   10 items  0.000000   0.000000   0.000000 (  0.000127)
+  100 items  0.000000   0.000000   0.000000 (  0.005636)
+  100 items  0.010000   0.000000   0.010000 (  0.004881)
+  100 items  0.000000   0.000000   0.000000 (  0.004676)
+ 1000 items  0.500000   0.000000   0.500000 (  0.505676)
+ 1000 items  0.490000   0.000000   0.490000 (  0.483469)
+ 1000 items  0.490000   0.000000   0.490000 (  0.497841)
+ 2000 items  1.950000   0.000000   1.950000 (  1.966324)
+ 2000 items  1.970000   0.000000   1.970000 (  1.975567)
+ 2000 items  1.900000   0.000000   1.900000 (  1.902315)
+ 4000 items  7.650000   0.010000   7.660000 (  7.672907)
+ 4000 items  7.720000   0.010000   7.730000 (  7.735615)
+ 4000 items  7.730000   0.000000   7.730000 (  7.756837)
+
+With "smaller subproblem" optimization: (about 20% slower)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001099)
+   10 items  0.000000   0.000000   0.000000 (  0.000110)
+   10 items  0.000000   0.000000   0.000000 (  0.000102)
+  100 items  0.010000   0.000000   0.010000 (  0.005462)
+  100 items  0.010000   0.000000   0.010000 (  0.005433)
+  100 items  0.000000   0.000000   0.000000 (  0.005409)
+ 1000 items  0.570000   0.000000   0.570000 (  0.569302)
+ 1000 items  0.570000   0.000000   0.570000 (  0.577496)
+ 1000 items  0.560000   0.000000   0.560000 (  0.555496)
+ 2000 items  2.330000   0.000000   2.330000 (  2.325537)
+ 2000 items  2.450000   0.000000   2.450000 (  2.464415)
+ 2000 items  2.470000   0.000000   2.470000 (  2.472999)
+ 4000 items  9.380000   0.010000   9.390000 (  9.406678)
+ 4000 items  9.320000   0.010000   9.330000 (  9.340727)
+ 4000 items  9.330000   0.010000   9.340000 (  9.358326)
+
+With "implement `values_match?` ourselves" optimization: (about twice as fast!)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001113)
+   10 items  0.000000   0.000000   0.000000 (  0.000074)
+   10 items  0.000000   0.000000   0.000000 (  0.000071)
+  100 items  0.000000   0.000000   0.000000 (  0.002558)
+  100 items  0.010000   0.000000   0.010000 (  0.002528)
+  100 items  0.000000   0.000000   0.000000 (  0.002555)
+ 1000 items  0.300000   0.000000   0.300000 (  0.306318)
+ 1000 items  0.260000   0.000000   0.260000 (  0.253526)
+ 1000 items  0.240000   0.000000   0.240000 (  0.246096)
+ 2000 items  1.070000   0.000000   1.070000 (  1.065989)
+ 2000 items  1.040000   0.000000   1.040000 (  1.047495)
+ 2000 items  1.080000   0.000000   1.080000 (  1.078392)
+ 4000 items  4.520000   0.000000   4.520000 (  4.529568)
+ 4000 items  4.570000   0.010000   4.580000 (  4.597785)
+ 4000 items  5.030000   0.010000   5.040000 (  5.079452)
+
+With `match_when_sorted?` optimization: (many orders of magnitude faster!)
+
+   10 items  0.010000   0.000000   0.010000 (  0.002044)
+   10 items  0.000000   0.000000   0.000000 (  0.000038)
+   10 items  0.000000   0.000000   0.000000 (  0.000031)
+  100 items  0.000000   0.000000   0.000000 (  0.000149)
+  100 items  0.000000   0.000000   0.000000 (  0.000137)
+  100 items  0.000000   0.000000   0.000000 (  0.000136)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001426)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001369)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001355)
+ 2000 items  0.010000   0.000000   0.010000 (  0.003304)
+ 2000 items  0.000000   0.000000   0.000000 (  0.002192)
+ 2000 items  0.000000   0.000000   0.000000 (  0.002849)
+ 4000 items  0.000000   0.000000   0.000000 (  0.007730)
+ 4000 items  0.010000   0.000000   0.010000 (  0.006074)
+ 4000 items  0.010000   0.000000   0.010000 (  0.006514)
+
+With e === a || a == e || values_match?(e,a)
+
+   10 items  0.000000   0.000000   0.000000 (  0.002202)
+   10 items  0.000000   0.000000   0.000000 (  0.000054)
+   10 items  0.000000   0.000000   0.000000 (  0.000046)
+  100 items  0.000000   0.000000   0.000000 (  0.000203)
+  100 items  0.000000   0.000000   0.000000 (  0.000199)
+  100 items  0.000000   0.000000   0.000000 (  0.000192)
+ 1000 items  0.010000   0.000000   0.010000 (  0.001438)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001419)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001474)
+ 2000 items  0.010000   0.000000   0.010000 (  0.003341)
+ 2000 items  0.000000   0.000000   0.000000 (  0.003224)
+ 2000 items  0.000000   0.000000   0.000000 (  0.003251)
+ 4000 items  0.010000   0.000000   0.010000 (  0.007156)
+ 4000 items  0.010000   0.000000   0.010000 (  0.006715)
+ 4000 items  0.000000   0.000000   0.000000 (  0.006676)
+
+With values_match?(e,a)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001173)
+   10 items  0.000000   0.000000   0.000000 (  0.000051)
+   10 items  0.000000   0.000000   0.000000 (  0.000026)
+  100 items  0.000000   0.000000   0.000000 (  0.000171)
+  100 items  0.000000   0.000000   0.000000 (  0.000138)
+  100 items  0.000000   0.000000   0.000000 (  0.000136)
+ 1000 items  0.010000   0.000000   0.010000 (  0.001506)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001486)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001510)
+ 2000 items  0.010000   0.000000   0.010000 (  0.003153)
+ 2000 items  0.000000   0.010000   0.010000 (  0.003883)
+ 2000 items  0.000000   0.000000   0.000000 (  0.003199)
+ 4000 items  0.010000   0.000000   0.010000 (  0.007178)
+ 4000 items  0.000000   0.000000   0.000000 (  0.006629)
+ 4000 items  0.010000   0.000000   0.010000 (  0.006435)
diff --git a/rspec-expectations/benchmarks/match_array/passing_with_duplicate_items.rb b/rspec-expectations/benchmarks/match_array/passing_with_duplicate_items.rb
new file mode 100644
index 0000000..f2d9391
--- /dev/null
+++ b/rspec-expectations/benchmarks/match_array/passing_with_duplicate_items.rb
@@ -0,0 +1,132 @@
+$LOAD_PATH.unshift "./lib"
+require 'benchmark'
+require 'rspec/expectations'
+
+extend RSpec::Matchers
+
+sizes = [10, 100, 1000, 2000]
+
+puts "rspec-expectations #{RSpec::Expectations::Version::STRING} -- #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+puts
+puts "Passing `match_array` expectation with lists of integers including duplicate values"
+puts
+
+Benchmark.benchmark do |bm|
+  sizes.each do |size|
+    actual    = Array.new(size) { rand(size / 2) }
+    expecteds = Array.new(3)    { actual.shuffle }
+    expecteds.each do |expected|
+      bm.report("#{size.to_s.rjust(5)} items") do
+        expect(actual).to match_array(expected)
+      end
+    end
+  end
+end
+
+__END__
+
+Before new composable matchers algo:
+
+   10 items  0.000000   0.000000   0.000000 (  0.000665)
+   10 items  0.000000   0.000000   0.000000 (  0.000027)
+   10 items  0.000000   0.000000   0.000000 (  0.000015)
+  100 items  0.000000   0.000000   0.000000 (  0.000250)
+  100 items  0.000000   0.000000   0.000000 (  0.000176)
+  100 items  0.000000   0.000000   0.000000 (  0.000181)
+ 1000 items  0.010000   0.000000   0.010000 (  0.013612)
+ 1000 items  0.020000   0.000000   0.020000 (  0.013409)
+ 1000 items  0.020000   0.000000   0.020000 (  0.018222)
+ 2000 items  0.060000   0.000000   0.060000 (  0.057428)
+ 2000 items  0.060000   0.000000   0.060000 (  0.058242)
+ 2000 items  0.060000   0.000000   0.060000 (  0.063026)
+
+After:
+
+   10 items  0.000000   0.000000   0.000000 (  0.001835)
+   10 items  0.000000   0.000000   0.000000 (  0.000327)
+   10 items  0.000000   0.000000   0.000000 (  0.000336)
+  100 items  0.030000   0.000000   0.030000 (  0.025134)
+  100 items  0.030000   0.000000   0.030000 (  0.032476)
+  100 items  0.020000   0.000000   0.020000 (  0.024273)
+ 1000 items  2.600000   0.040000   2.640000 (  2.649328)
+ 1000 items  2.510000   0.020000   2.530000 (  2.523448)
+ 1000 items  2.470000   0.000000   2.470000 (  2.476770)
+ 2000 items 11.590000   0.110000  11.700000 ( 11.719525)
+ 2000 items 10.750000   0.080000  10.830000 ( 10.845655)
+ 2000 items 11.140000   0.080000  11.220000 ( 11.241852)
+
+With "smaller subproblem" optimization: (about 35% faster)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001236)
+   10 items  0.000000   0.000000   0.000000 (  0.000278)
+   10 items  0.000000   0.000000   0.000000 (  0.000293)
+  100 items  0.010000   0.000000   0.010000 (  0.013229)
+  100 items  0.020000   0.000000   0.020000 (  0.013932)
+  100 items  0.020000   0.000000   0.020000 (  0.019739)
+ 1000 items  1.580000   0.030000   1.610000 (  1.622586)
+ 1000 items  1.670000   0.020000   1.690000 (  1.683174)
+ 1000 items  1.570000   0.010000   1.580000 (  1.588718)
+ 2000 items  7.030000   0.100000   7.130000 (  7.139178)
+ 2000 items  7.220000   0.090000   7.310000 (  7.328606)
+ 2000 items  6.930000   0.130000   7.060000 (  7.070295)
+
+With "implement `values_match?` ourselves" optimization: (about 20% faster)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001352)
+   10 items  0.000000   0.000000   0.000000 (  0.000313)
+   10 items  0.000000   0.000000   0.000000 (  0.000298)
+  100 items  0.010000   0.000000   0.010000 (  0.011200)
+  100 items  0.010000   0.000000   0.010000 (  0.013465)
+  100 items  0.020000   0.000000   0.020000 (  0.021589)
+ 1000 items  1.320000   0.030000   1.350000 (  1.350071)
+ 1000 items  1.280000   0.020000   1.300000 (  1.298206)
+ 1000 items  1.370000   0.010000   1.380000 (  1.392149)
+ 2000 items  6.120000   0.110000   6.230000 (  6.252104)
+ 2000 items  6.170000   0.090000   6.260000 (  6.270807)
+ 2000 items  5.910000   0.150000   6.060000 (  6.066389)
+
+With `match_when_sorted?` optimization: (many orders of magnitude faster!)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001134)
+   10 items  0.000000   0.000000   0.000000 (  0.000029)
+   10 items  0.000000   0.000000   0.000000 (  0.000020)
+  100 items  0.000000   0.000000   0.000000 (  0.000070)
+  100 items  0.000000   0.000000   0.000000 (  0.000066)
+  100 items  0.000000   0.000000   0.000000 (  0.000065)
+ 1000 items  0.000000   0.000000   0.000000 (  0.000612)
+ 1000 items  0.000000   0.000000   0.000000 (  0.000608)
+ 1000 items  0.000000   0.000000   0.000000 (  0.000613)
+ 2000 items  0.010000   0.000000   0.010000 (  0.001235)
+ 2000 items  0.000000   0.000000   0.000000 (  0.001282)
+ 2000 items  0.000000   0.000000   0.000000 (  0.001227)
+
+With e === a || a == e || values_match?(e,a)
+
+   10 items  0.010000   0.000000   0.010000 (  0.001258)
+   10 items  0.000000   0.000000   0.000000 (  0.000034)
+   10 items  0.000000   0.000000   0.000000 (  0.000027)
+  100 items  0.000000   0.000000   0.000000 (  0.000124)
+  100 items  0.000000   0.000000   0.000000 (  0.000151)
+  100 items  0.000000   0.000000   0.000000 (  0.000121)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001212)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001193)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001293)
+ 2000 items  0.000000   0.000000   0.000000 (  0.002433)
+ 2000 items  0.010000   0.000000   0.010000 (  0.002351)
+ 2000 items  0.000000   0.000000   0.000000 (  0.002404)
+
+With values_match?(e,a)
+
+   10 items  0.000000   0.000000   0.000000 (  0.001202)
+   10 items  0.000000   0.000000   0.000000 (  0.000028)
+   10 items  0.000000   0.000000   0.000000 (  0.000024)
+  100 items  0.000000   0.000000   0.000000 (  0.000147)
+  100 items  0.000000   0.000000   0.000000 (  0.000122)
+  100 items  0.000000   0.000000   0.000000 (  0.000142)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001201)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001233)
+ 1000 items  0.000000   0.000000   0.000000 (  0.001221)
+ 2000 items  0.010000   0.000000   0.010000 (  0.002382)
+ 2000 items  0.000000   0.000000   0.000000 (  0.002353)
+ 2000 items  0.000000   0.000000   0.000000 (  0.002371)
diff --git a/rspec-expectations/benchmarks/match_array/rubyprof/passing_with_distinct_items.rb b/rspec-expectations/benchmarks/match_array/rubyprof/passing_with_distinct_items.rb
new file mode 100644
index 0000000..05c837a
--- /dev/null
+++ b/rspec-expectations/benchmarks/match_array/rubyprof/passing_with_distinct_items.rb
@@ -0,0 +1,9 @@
+$LOAD_PATH.unshift "./lib"
+require 'rspec/expectations'
+require 'securerandom'
+
+extend RSpec::Matchers
+
+actual    = Array.new(1000) { SecureRandom.uuid }
+expected  = actual.shuffle
+expect(actual).to match_array(expected)
diff --git a/rspec-expectations/benchmarks/matcher_dsl_vs_classes.rb b/rspec-expectations/benchmarks/matcher_dsl_vs_classes.rb
new file mode 100644
index 0000000..8e9f9bf
--- /dev/null
+++ b/rspec-expectations/benchmarks/matcher_dsl_vs_classes.rb
@@ -0,0 +1,180 @@
+require 'benchmark'
+require 'rspec/expectations'
+
+include RSpec::Expectations
+include RSpec::Matchers
+
+RSpec::Matchers.define :eq_using_dsl do |expected|
+  match do |actual|
+    actual == expected
+  end
+end
+
+n = 1000
+
+puts "3 runs of #{n} times for each example running #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+puts "passing examples: 5.should eq(5)"
+puts "* using the DSL"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        5.should eq_using_dsl(5)
+      end
+    end
+  end
+end
+
+puts
+puts "* using a class"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        5.should eq(5)
+      end
+    end
+  end
+end
+
+puts
+puts "failing examples: 5.should eq(3)"
+puts "* using the DSL"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        5.should eq_using_dsl(3) rescue nil
+      end
+    end
+  end
+end
+
+puts
+puts "* using a class"
+Benchmark.benchmark do |bm|
+  3.times do
+    bm.report do
+      n.times do
+        5.should eq(3) rescue nil
+      end
+    end
+  end
+end
+
+# 3 runs of 1000 times for each example running ruby/1.8.7
+# passing examples: 5.should eq(5)
+# * using the DSL
+#   0.340000   0.000000   0.340000 (  0.342052)
+#   0.330000   0.010000   0.340000 (  0.340618)
+#   0.340000   0.000000   0.340000 (  0.339149)
+#
+# * using a class
+#   0.000000   0.000000   0.000000 (  0.003762)
+#   0.010000   0.000000   0.010000 (  0.004192)
+#   0.000000   0.000000   0.000000 (  0.003791)
+#
+# failing examples: 5.should eq(3)
+# * using the DSL
+#   0.380000   0.000000   0.380000 (  0.384415)
+#   0.380000   0.010000   0.390000 (  0.381604)
+#   0.370000   0.000000   0.370000 (  0.380255)
+#
+# * using a class
+#   0.040000   0.000000   0.040000 (  0.034528)
+#   0.030000   0.000000   0.030000 (  0.032021)
+#   0.060000   0.010000   0.070000 (  0.067579)
+#
+# 3 runs of 1000 times for each example running ruby/1.9.2
+# passing examples: 5.should eq(5)
+# * using the DSL
+#   0.250000   0.010000   0.260000 (  0.249692)
+#   0.250000   0.000000   0.250000 (  0.253856)
+#   0.230000   0.000000   0.230000 (  0.232787)
+#
+# * using a class
+#   0.000000   0.000000   0.000000 (  0.001069)
+#   0.000000   0.000000   0.000000 (  0.001041)
+#   0.000000   0.000000   0.000000 (  0.001023)
+#
+# failing examples: 5.should eq(3)
+# * using the DSL
+#   0.370000   0.000000   0.370000 (  0.377139)
+#   0.360000   0.010000   0.370000 (  0.358379)
+#   0.370000   0.000000   0.370000 (  0.373795)
+#
+# * using a class
+#   0.060000   0.010000   0.070000 (  0.073325)
+#   0.050000   0.000000   0.050000 (  0.053562)
+#   0.070000   0.000000   0.070000 (  0.075382)
+#
+# 3 runs of 1000 times for each example running ruby/1.9.3
+# passing examples: 5.should eq(5)
+# * using the DSL
+#     0.210000   0.000000   0.210000 (  0.219539)
+#    0.220000   0.010000   0.230000 (  0.217905)
+#    0.220000   0.000000   0.220000 (  0.219657)
+#
+# * using a class
+#     0.000000   0.000000   0.000000 (  0.001054)
+#    0.000000   0.000000   0.000000 (  0.001048)
+#    0.000000   0.000000   0.000000 (  0.001035)
+#
+# failing examples: 5.should eq(3)
+# * using the DSL
+#     0.350000   0.000000   0.350000 (  0.351742)
+#    0.360000   0.000000   0.360000 (  0.362456)
+#    0.340000   0.010000   0.350000 (  0.351098)
+#
+# * using a class
+#     0.080000   0.000000   0.080000 (  0.079964)
+#    0.080000   0.000000   0.080000 (  0.076579)
+#    0.070000   0.000000   0.070000 (  0.080587)
+#
+# 3 runs of 1000 times for each example running rbx/1.8.7
+# passing examples: 5.should eq(5)
+# * using the DSL
+#   1.926107   0.009784   1.935891 (  1.629354)
+#   0.583860   0.004390   0.588250 (  0.580396)
+#   0.868571   0.003510   0.872081 (  0.796644)
+#
+# * using a class
+#   0.002652   0.000013   0.002665 (  0.002679)
+#   0.001845   0.000016   0.001861 (  0.001848)
+#   0.002656   0.000010   0.002666 (  0.001823)
+#
+# failing examples: 5.should eq(3)
+# * using the DSL
+#   0.694148   0.002006   0.696154 (  0.648551)
+#   1.063773   0.004653   1.068426 (  0.998837)
+#   0.643594   0.001356   0.644950 (  0.638358)
+#
+# * using a class
+#   0.020139   0.000036   0.020175 (  0.020161)
+#   0.097540   0.000575   0.098115 (  0.084680)
+#   0.058366   0.000269   0.058635 (  0.044372)
+#
+# 3 runs of 1000 times for each example running jruby/1.8.7
+# passing examples: 5.should eq(5)
+# * using the DSL
+#   0.355000   0.000000   0.355000 (  0.355000)
+#   0.261000   0.000000   0.261000 (  0.261000)
+#   0.242000   0.000000   0.242000 (  0.242000)
+#
+# * using a class
+#   0.007000   0.000000   0.007000 (  0.007000)
+#   0.004000   0.000000   0.004000 (  0.004000)
+#   0.001000   0.000000   0.001000 (  0.001000)
+#
+# failing examples: 5.should eq(3)
+# * using the DSL
+#   0.507000   0.000000   0.507000 (  0.507000)
+#   0.468000   0.000000   0.468000 (  0.468000)
+#   0.476000   0.000000   0.476000 (  0.476000)
+#
+# * using a class
+#   0.259000   0.000000   0.259000 (  0.259000)
+#   0.521000   0.000000   0.521000 (  0.521000)
+#   0.244000   0.000000   0.244000 (  0.244000)
+#
diff --git a/rspec-expectations/benchmarks/method_to_proc.rb b/rspec-expectations/benchmarks/method_to_proc.rb
new file mode 100644
index 0000000..9595780
--- /dev/null
+++ b/rspec-expectations/benchmarks/method_to_proc.rb
@@ -0,0 +1,72 @@
+require 'benchmark'
+
+n = 10_000_000
+
+puts "3 runs of #{n} times running #{RUBY_ENGINE}/#{RUBY_VERSION}"
+
+def foo(x); end
+def extract_method_proc(&b); b; end
+
+Benchmark.benchmark do |bm|
+  puts "calling foo = method(:foo).to_proc"
+  foo_proc = method(:foo).to_proc
+
+  3.times do
+    bm.report do
+      n.times { foo_proc.call(1) }
+    end
+  end
+
+  puts "calling Proc.new { |x| foo(x) }"
+  foo_proc = extract_method_proc { |x| foo(x) }
+
+  3.times do
+    bm.report do
+      n.times { foo_proc.call(1) }
+    end
+  end
+end
+
+__END__
+
+Surprisingly, `Method#to_proc` is slower, except on 1.9.3 where it's a wash.
+
+3 runs of 10000000 times running ruby/2.1.1
+calling foo = method(:foo).to_proc
+   2.190000   0.010000   2.200000 (  2.206627)
+   2.370000   0.010000   2.380000 (  2.391100)
+   2.190000   0.000000   2.190000 (  2.193119)
+calling Proc.new { |x| foo(x) }
+   1.640000   0.000000   1.640000 (  1.648841)
+   1.610000   0.000000   1.610000 (  1.617186)
+   1.590000   0.010000   1.600000 (  1.600570)
+
+3 runs of 10000000 times running ruby/2.0.0
+calling foo = method(:foo).to_proc
+   2.170000   0.010000   2.180000 (  2.192418)
+   2.140000   0.000000   2.140000 (  2.141015)
+   2.150000   0.010000   2.160000 (  2.172794)
+calling Proc.new { |x| foo(x) }
+   1.680000   0.000000   1.680000 (  1.686904)
+   1.650000   0.000000   1.650000 (  1.654465)
+   1.640000   0.000000   1.640000 (  1.648229)
+
+3 runs of 10000000 times running ruby/1.9.3
+ calling foo = method(:foo).to_proc
+   2.440000   0.010000   2.450000 (  2.457211)
+   2.430000   0.000000   2.430000 (  2.450140)
+   2.480000   0.010000   2.490000 (  2.496520)
+calling Proc.new { |x| foo(x) }
+   2.400000   0.000000   2.400000 (  2.415641)
+   2.480000   0.000000   2.480000 (  2.489564)
+   2.460000   0.000000   2.460000 (  2.477368)
+
+3 runs of 10000000 times running ruby/1.9.2
+calling foo = method(:foo).to_proc
+  2.490000   0.010000   2.500000 (  2.502401)
+  2.580000   0.000000   2.580000 (  2.589306)
+  2.310000   0.010000   2.320000 (  2.328342)
+calling Proc.new { |x| foo(x) }
+  1.860000   0.000000   1.860000 (  1.866537)
+  1.860000   0.000000   1.860000 (  1.871056)
+  1.850000   0.010000   1.860000 (  1.857426)
diff --git a/rspec-expectations/benchmarks/output_stringio_vs_tempfile.rb b/rspec-expectations/benchmarks/output_stringio_vs_tempfile.rb
new file mode 100644
index 0000000..5635e5b
--- /dev/null
+++ b/rspec-expectations/benchmarks/output_stringio_vs_tempfile.rb
@@ -0,0 +1,31 @@
+require 'rubygems'
+require 'bundler/setup'
+require 'benchmark'
+require 'rspec/expectations'
+include RSpec::Matchers
+
+n = 100_000
+
+Benchmark.bm(25) do |bm|
+  bm.report("to_stdout with StringIO") do
+    n.times { expect {}.not_to output('foo').to_stdout }
+  end
+
+  bm.report("to_stdout with Tempfile") do
+    n.times { expect {}.not_to output('foo').to_stdout_from_any_process }
+  end
+
+  bm.report("to_stderr with StringIO") do
+    n.times { expect {}.not_to output('foo').to_stderr }
+  end
+
+  bm.report("to_stderr with Tempfile") do
+    n.times { expect {}.not_to output('foo').to_stderr_from_any_process }
+  end
+end
+
+#                                 user     system      total        real
+# to_stdout with StringIO     0.470000   0.010000   0.480000 (  0.467317)
+# to_stdout with Tempfile     8.920000   7.420000  16.340000 ( 16.355174)
+# to_stderr with StringIO     0.460000   0.000000   0.460000 (  0.454059)
+# to_stderr with Tempfile     8.930000   7.560000  16.490000 ( 16.494696)
diff --git a/rspec-expectations/benchmarks/set_vs_array_include.rb b/rspec-expectations/benchmarks/set_vs_array_include.rb
new file mode 100644
index 0000000..0977792
--- /dev/null
+++ b/rspec-expectations/benchmarks/set_vs_array_include.rb
@@ -0,0 +1,68 @@
+require 'benchmark'
+require 'set'
+
+n = 10000000
+
+array = [
+  :@name, :@declarations, :@diffable, :@messages,
+  :@match_block, :@match_for_should_not_block,
+  :@expected_exception
+]
+set = array.to_set
+
+puts "Positive examples: "
+Benchmark.bm(25) do |x|
+  array.each_with_index do |var, i|
+    x.report("set.include?(item #{i})  ") do
+      n.times { set.include?(var) }
+    end
+
+    x.report("array.include?(item #{i})") do
+      n.times { array.include?(var) }
+    end
+
+    puts "=" * 80
+  end
+end
+
+puts "\n\nNegative examples: "
+Benchmark.bm(5) do |x|
+  x.report("set  ") do
+    n.times { set.include?(:@other) }
+  end
+
+  x.report("array") do
+    n.times { array.include?(:@other) }
+  end
+end
+
+# Positive examples:
+#                                user     system      total        real
+# set.include?(item 0)       2.000000   0.010000   2.010000 (  1.999305)
+# array.include?(item 0)     1.170000   0.000000   1.170000 (  1.173168)
+# ================================================================================
+# set.include?(item 1)       2.020000   0.000000   2.020000 (  2.016389)
+# array.include?(item 1)     1.580000   0.000000   1.580000 (  1.585301)
+# ================================================================================
+# set.include?(item 2)       1.980000   0.010000   1.990000 (  1.984699)
+# array.include?(item 2)     2.170000   0.000000   2.170000 (  2.167163)
+# ================================================================================
+# set.include?(item 3)       2.110000   0.010000   2.120000 (  2.125914)
+# array.include?(item 3)     2.450000   0.000000   2.450000 (  2.445224)
+# ================================================================================
+# set.include?(item 4)       2.090000   0.010000   2.100000 (  2.094182)
+# array.include?(item 4)     2.920000   0.000000   2.920000 (  2.924850)
+# ================================================================================
+# set.include?(item 5)       2.000000   0.000000   2.000000 (  2.000656)
+# array.include?(item 5)     3.540000   0.010000   3.550000 (  3.547563)
+# ================================================================================
+# set.include?(item 6)       2.030000   0.000000   2.030000 (  2.032430)
+# array.include?(item 6)     3.800000   0.010000   3.810000 (  3.810014)
+# ================================================================================
+
+
+# Negative examples:
+#            user     system      total        real
+# set    1.940000   0.000000   1.940000 (  1.941780)
+# array  4.240000   0.010000   4.250000 (  4.238137)
+
diff --git a/rspec-expectations/cucumber.yml b/rspec-expectations/cucumber.yml
new file mode 100644
index 0000000..0383804
--- /dev/null
+++ b/rspec-expectations/cucumber.yml
@@ -0,0 +1,10 @@
+<%
+def tags(tag)
+  tags = [tag]
+  tags << "~@ruby-1.9" if RUBY_VERSION.to_f < 1.9
+  tags.join(" --tags ")
+end
+%>
+
+default: --require features --tags <%= tags("~@wip") %> --format progress
+wip: --require features --tags <%= tags("@wip:3") --wip features
diff --git a/rspec-expectations/features/.nav b/rspec-expectations/features/.nav
new file mode 100644
index 0000000..23fc251
--- /dev/null
+++ b/rspec-expectations/features/.nav
@@ -0,0 +1,41 @@
+- built_in_matchers:
+  - equality.feature
+  - comparisons.feature
+  - predicates.feature
+  - types.feature
+  - all.feature
+  - be.feature
+  - be_within.feature
+  - exist.feature
+  - change.feature
+  - contain_exactly.feature
+  - cover.feature
+  - end_with.feature
+  - exist.feature
+  - have.feature
+  - have_attributes.feature
+  - include.feature
+  - match.feature
+  - operators.feature
+  - raise_error.feature
+  - respond_to.feature
+  - satisfy.feature
+  - start_with.feature
+  - throw_symbol.feature
+  - yield.feature
+- custom_matchers:
+  - define_matcher.feature
+  - define_diffable_matcher.feature
+  - define_matcher_with_fluent_interface.feature
+  - access_running_example.feature
+  - define_matcher_outside_rspec.feature
+- composing_matchers.feature
+- compound_expectations.feature
+- define_negated_matcher.feature
+- customized_message.feature
+- diffing.feature
+- implicit_docstrings.feature
+- syntax_configuration.feature
+- test_frameworks:
+  - test_unit.feature
+- Changelog.md
diff --git a/rspec-expectations/features/README.md b/rspec-expectations/features/README.md
new file mode 100644
index 0000000..a985bbb
--- /dev/null
+++ b/rspec-expectations/features/README.md
@@ -0,0 +1,49 @@
+rspec-expectations is used to define expected outcomes.
+
+    RSpec.describe Account do
+      it "has a balance of zero when first created" do
+        expect(Account.new.balance).to eq(Money.new(0))
+      end
+    end
+
+## Basic structure
+
+The basic structure of an rspec expectation is:
+
+    expect(actual).to matcher(expected)
+    expect(actual).not_to matcher(expected)
+
+Note: You can also use `expect(..).to_not` instead of `expect(..).not_to`.
+      One is an alias to the other, so you can use whichever reads better to you.
+
+#### Examples
+
+    expect(5).to eq(5)
+    expect(5).not_to eq(4)
+
+## What is a matcher?
+
+A matcher is any object that responds to the following methods:
+
+    matches?(actual)
+    failure_message
+
+These methods are also part of the matcher protocol, but are optional:
+
+    does_not_match?(actual)
+    failure_message_when_negated
+    description
+    supports_block_expectations?
+
+RSpec ships with a number of built-in matchers and a DSL for writing custom
+matchers.
+
+## Issues
+
+The documentation for rspec-expectations is a work in progress. We'll be adding
+Cucumber features over time, and clarifying existing ones.  If you have
+specific features you'd like to see added, find the existing documentation
+incomplete or confusing, or, better yet, wish to write a missing Cucumber
+feature yourself, please [submit an
+issue](http://github.com/rspec/rspec-expectations/issues) or a [pull
+request](http://github.com/rspec/rspec-expectations).
diff --git a/rspec-expectations/features/built_in_matchers/README.md b/rspec-expectations/features/built_in_matchers/README.md
new file mode 100644
index 0000000..10f5a16
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/README.md
@@ -0,0 +1,137 @@
+rspec-expectations ships with a number of built-in matchers. Each matcher can be used
+with `expect(..).to` or `expect(..).not_to` to define positive and negative expectations
+respectively on an object. Most matchers can also be accessed using the `(...).should` and
+`(...).should_not` syntax; see [using should syntax](https://github.com/rspec/rspec-expectations/blob/master/Should.md) for why we recommend using `expect`.
+
+e.g.
+
+    expect(result).to   eq(3)
+    expect(list).not_to be_empty
+    pi.should be > 3
+
+## Object identity
+
+    expect(actual).to be(expected) # passes if actual.equal?(expected)
+
+## Object equivalence
+
+    expect(actual).to eq(expected) # passes if actual == expected
+
+## Optional APIs for identity/equivalence
+
+    expect(actual).to eql(expected)   # passes if actual.eql?(expected)
+    expect(actual).to equal(expected) # passes if actual.equal?(expected)
+
+    # NOTE: `expect` does not support `==` matcher.
+
+## Comparisons
+
+    expect(actual).to be >  expected
+    expect(actual).to be >= expected
+    expect(actual).to be <= expected
+    expect(actual).to be <  expected
+    expect(actual).to be_between(minimum, maximum).inclusive
+    expect(actual).to be_between(minimum, maximum).exclusive
+    expect(actual).to match(/expression/)
+    expect(actual).to be_within(delta).of(expected)
+    expect(actual).to start_with expected
+    expect(actual).to end_with expected
+
+    # NOTE: `expect` does not support `=~` matcher.
+
+## Types/classes/response
+
+    expect(actual).to be_instance_of(expected)
+    expect(actual).to be_kind_of(expected)
+    expect(actual).to respond_to(expected)
+
+## Truthiness and existentialism
+
+    expect(actual).to be_truthy    # passes if actual is truthy (not nil or false)
+    expect(actual).to be true      # passes if actual == true
+    expect(actual).to be_falsey    # passes if actual is falsy (nil or false)
+    expect(actual).to be false     # passes if actual == false
+    expect(actual).to be_nil       # passes if actual is nil
+    expect(actual).to exist        # passes if actual.exist? and/or actual.exists? are truthy
+    expect(actual).to exist(*args) # passes if actual.exist?(*args) and/or actual.exists?(*args) are truthy
+
+## Expecting errors
+
+    expect { ... }.to raise_error
+    expect { ... }.to raise_error(ErrorClass)
+    expect { ... }.to raise_error("message")
+    expect { ... }.to raise_error(ErrorClass, "message")
+
+## Expecting throws
+
+    expect { ... }.to throw_symbol
+    expect { ... }.to throw_symbol(:symbol)
+    expect { ... }.to throw_symbol(:symbol, 'value')
+
+## Predicate matchers
+
+    expect(actual).to be_xxx         # passes if actual.xxx?
+    expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg)
+
+### Examples
+
+    expect([]).to      be_empty
+    expect(:a => 1).to have_key(:a)
+
+## Collection membership
+
+    expect(actual).to include(expected)
+    expect(array).to match_array(expected_array)
+    # ...which is the same as:
+    expect(array).to contain_exactly(individual, elements)
+
+### Examples
+
+    expect([1, 2, 3]).to     include(1)
+    expect([1, 2, 3]).to     include(1, 2)
+    expect(:a => 'b').to     include(:a => 'b')
+    expect("this string").to include("is str")
+    expect([1, 2, 3]).to     contain_exactly(2, 1, 3)
+    expect([1, 2, 3]).to     match_array([3, 2, 1])
+
+## Ranges (1.9 only)
+
+    expect(1..10).to cover(3)
+
+## Change observation
+
+    expect { object.action }.to change(object, :value).from(old).to(new)
+    expect { object.action }.to change(object, :value).by(delta)
+    expect { object.action }.to change(object, :value).by_at_least(minimum_delta)
+    expect { object.action }.to change(object, :value).by_at_most(maximum_delta)
+
+### Examples
+
+    expect { a += 1 }.to change { a }.by(1)
+    expect { a += 3 }.to change { a }.from(2)
+    expect { a += 3 }.to change { a }.by_at_least(2)
+
+## Satisfy
+
+    expect(actual).to satisfy { |value| value == expected }
+
+## Output capture
+
+    expect { actual }.to output("some output").to_stdout
+    expect { actual }.to output("some error").to_stderr
+
+## Block expectation
+
+    expect { |b| object.action(&b) }.to yield_control
+    expect { |b| object.action(&b) }.to yield_with_no_args           # only matches no args
+    expect { |b| object.action(&b) }.to yield_with_args              # matches any args
+    expect { |b| object.action(&b) }.to yield_successive_args(*args) # matches args against multiple yields
+
+### Examples
+
+    expect { |b| User.transaction(&b) }.to yield_control
+    expect { |b| User.transaction(&b) }.to yield_with_no_args
+    expect { |b| 5.tap(&b)            }.not_to yield_with_no_args         # because it yields with `5`
+    expect { |b| 5.tap(&b)            }.to yield_with_args(5)             # because 5 == 5
+    expect { |b| 5.tap(&b)            }.to yield_with_args(Fixnum)        # because Fixnum === 5
+    expect { |b| [1, 2, 3].each(&b)   }.to yield_successive_args(1, 2, 3)
diff --git a/rspec-expectations/features/built_in_matchers/all.feature b/rspec-expectations/features/built_in_matchers/all.feature
new file mode 100644
index 0000000..c07c5b0
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/all.feature
@@ -0,0 +1,60 @@
+Feature: `all` matcher
+
+  Use the `all` matcher to specify that a collection's objects all pass an expected matcher.
+  This works on any enumerable object.
+
+    ```ruby
+    expect([1, 3, 5]).to all( be_odd )
+    expect([1, 3, 5]).to all( be_an(Integer) )
+    expect([1, 3, 5]).to all( be < 10 )
+    expect([1, 3, 4]).to all( be_odd ) # fails
+    ```
+
+  The matcher also supports compound matchers:
+
+    ```ruby
+    expect([1, 3, 5]).to all( be_odd.and be < 10 )
+    expect([1, 4, 21]).to all( be_odd.or be < 10 )
+    ```
+
+  Scenario: array usage
+    Given a file named "array_all_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe [1, 3, 5] do
+        it { is_expected.to all( be_odd ) }
+        it { is_expected.to all( be_an(Integer) ) }
+        it { is_expected.to all( be < 10 ) }
+
+        # deliberate failures
+        it { is_expected.to all( be_even ) }
+        it { is_expected.to all( be_a(String) ) }
+        it { is_expected.to all( be > 2 ) }
+      end
+      """
+    When I run `rspec array_all_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 6 examples, 3 failures                        |
+      | expected [1, 3, 5] to all be even             |
+      | expected [1, 3, 5] to all be a kind of String |
+      | expected [1, 3, 5] to all be > 2              |
+
+  Scenario: compound matcher usage
+    Given a file named "compound_all_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe ['anything', 'everything', 'something'] do
+        it { is_expected.to all( be_a(String).and include("thing") ) }
+        it { is_expected.to all( be_a(String).and end_with("g") ) }
+        it { is_expected.to all( start_with("s").or include("y") ) }
+
+        # deliberate failures
+        it { is_expected.to all( include("foo").and include("bar") ) }
+        it { is_expected.to all( be_a(String).and start_with("a") ) }
+        it { is_expected.to all( start_with("a").or include("z") ) }
+      end
+      """
+    When I run `rspec compound_all_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 6 examples, 3 failures                                                                         |
+      | expected ["anything", "everything", "something"] to all include "foo" and include "bar"        |
+      | expected ["anything", "everything", "something"] to all be a kind of String and start with "a" |
+      | expected ["anything", "everything", "something"] to all start with "a" or include "z"          |
diff --git a/rspec-expectations/features/built_in_matchers/be.feature b/rspec-expectations/features/built_in_matchers/be.feature
new file mode 100644
index 0000000..6f3522c
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/be.feature
@@ -0,0 +1,175 @@
+Feature: `be` matchers
+
+  There are several related "be" matchers:
+
+    ```ruby
+    expect(obj).to be_truthy  # passes if obj is truthy (not nil or false)
+    expect(obj).to be_falsey  # passes if obj is falsy (nil or false)
+    expect(obj).to be_nil     # passes if obj is nil
+    expect(obj).to be         # passes if obj is truthy (not nil or false)
+    ```
+
+  Scenario: be_truthy matcher
+    Given a file named "be_truthy_spec.rb" with:
+      """ruby
+      RSpec.describe "be_truthy matcher" do
+        specify { expect(true).to be_truthy }
+        specify { expect(7).to be_truthy }
+        specify { expect("foo").to be_truthy }
+        specify { expect(nil).not_to be_truthy }
+        specify { expect(false).not_to be_truthy }
+
+        # deliberate failures
+        specify { expect(true).not_to be_truthy }
+        specify { expect(7).not_to be_truthy }
+        specify { expect("foo").not_to be_truthy }
+        specify { expect(nil).to be_truthy }
+        specify { expect(false).to be_truthy }
+      end
+      """
+    When I run `rspec be_truthy_spec.rb`
+    Then the output should contain "10 examples, 5 failures"
+    And the output should contain:
+      """
+             expected: falsey value
+                  got: true
+      """
+    And the output should contain:
+      """
+             expected: falsey value
+                  got: 7
+      """
+    And the output should contain:
+      """
+             expected: falsey value
+                  got: "foo"
+      """
+    And the output should contain:
+      """
+             expected: truthy value
+                  got: nil
+      """
+    And the output should contain:
+      """
+             expected: truthy value
+                  got: false
+      """
+
+  Scenario: be_falsey matcher
+    Given a file named "be_falsey_spec.rb" with:
+      """ruby
+      RSpec.describe "be_falsey matcher" do
+        specify { expect(nil).to be_falsey }
+        specify { expect(false).to be_falsey }
+        specify { expect(true).not_to be_falsey }
+        specify { expect(7).not_to be_falsey }
+        specify { expect("foo").not_to be_falsey }
+
+        # deliberate failures
+        specify { expect(nil).not_to be_falsey }
+        specify { expect(false).not_to be_falsey }
+        specify { expect(true).to be_falsey }
+        specify { expect(7).to be_falsey }
+        specify { expect("foo").to be_falsey }
+      end
+      """
+    When I run `rspec be_falsey_spec.rb`
+    Then the output should contain "10 examples, 5 failures"
+    And the output should contain:
+      """
+             expected: truthy value
+                  got: nil
+      """
+    And the output should contain:
+      """
+             expected: truthy value
+                  got: false
+      """
+    And the output should contain:
+      """
+             expected: falsey value
+                  got: true
+      """
+    And the output should contain:
+      """
+             expected: falsey value
+                  got: 7
+      """
+    And the output should contain:
+      """
+             expected: falsey value
+                  got: "foo"
+      """
+
+  Scenario: be_nil matcher
+    Given a file named "be_nil_spec.rb" with:
+      """ruby
+      RSpec.describe "be_nil matcher" do
+        specify { expect(nil).to be_nil }
+        specify { expect(false).not_to be_nil }
+        specify { expect(true).not_to be_nil }
+        specify { expect(7).not_to be_nil }
+        specify { expect("foo").not_to be_nil }
+
+        # deliberate failures
+        specify { expect(nil).not_to be_nil }
+        specify { expect(false).to be_nil }
+        specify { expect(true).to be_nil }
+        specify { expect(7).to be_nil }
+        specify { expect("foo").to be_nil }
+      end
+      """
+    When I run `rspec be_nil_spec.rb`
+    Then the output should contain "10 examples, 5 failures"
+    And the output should contain:
+      """
+             expected: not nil
+                  got: nil
+      """
+    And the output should contain:
+      """
+             expected: nil
+                  got: false
+      """
+    And the output should contain:
+      """
+             expected: nil
+                  got: true
+      """
+    And the output should contain:
+      """
+             expected: nil
+                  got: 7
+      """
+    And the output should contain:
+      """
+             expected: nil
+                  got: "foo"
+      """
+
+  Scenario: be matcher
+    Given a file named "be_spec.rb" with:
+      """ruby
+      RSpec.describe "be_matcher" do
+        specify { expect(true).to be }
+        specify { expect(7).to be }
+        specify { expect("foo").to be }
+        specify { expect(nil).not_to be }
+        specify { expect(false).not_to be }
+
+        # deliberate failures
+        specify { expect(true).not_to be }
+        specify { expect(7).not_to be }
+        specify { expect("foo").not_to be }
+        specify { expect(nil).to be }
+        specify { expect(false).to be }
+      end
+      """
+    When I run `rspec be_spec.rb`
+    Then the output should contain all of these:
+      | 10 examples, 5 failures             |
+      | expected true to evaluate to false  |
+      | expected 7 to evaluate to false     |
+      | expected "foo" to evaluate to false |
+      | expected nil to evaluate to true    |
+      | expected false to evaluate to true  |
diff --git a/rspec-expectations/features/built_in_matchers/be_within.feature b/rspec-expectations/features/built_in_matchers/be_within.feature
new file mode 100644
index 0000000..0bbe5fa
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/be_within.feature
@@ -0,0 +1,48 @@
+Feature: `be_within` matcher
+
+  Normal equality expectations do not work well for floating point values.
+  Consider this irb session:
+
+      > radius = 3
+        => 3
+      > area_of_circle = radius * radius * Math::PI
+        => 28.2743338823081
+      > area_of_circle == 28.2743338823081
+        => false
+
+  Instead, you should use the be_within matcher to check that the value is within a delta of
+  your expected value:
+
+    ```ruby
+    expect(area_of_circle).to be_within(0.1).of(28.3)
+    ```
+
+  Note that the difference between the actual and expected values must be smaller than your
+  delta; if it is equal, the matcher will fail.
+
+  Scenario: basic usage
+    Given a file named "be_within_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe 27.5 do
+        it { is_expected.to be_within(0.5).of(27.9) }
+        it { is_expected.to be_within(0.5).of(28.0) }
+        it { is_expected.to be_within(0.5).of(27.1) }
+        it { is_expected.to be_within(0.5).of(27.0) }
+
+        it { is_expected.not_to be_within(0.5).of(28.1) }
+        it { is_expected.not_to be_within(0.5).of(26.9) }
+
+        # deliberate failures
+        it { is_expected.not_to be_within(0.5).of(28) }
+        it { is_expected.not_to be_within(0.5).of(27) }
+        it { is_expected.to be_within(0.5).of(28.1) }
+        it { is_expected.to be_within(0.5).of(26.9) }
+      end
+      """
+    When I run `rspec be_within_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 10 examples, 4 failures                     |
+      | expected 27.5 not to be within 0.5 of 28   |
+      | expected 27.5 not to be within 0.5 of 27   |
+      | expected 27.5 to be within 0.5 of 28.1     |
+      | expected 27.5 to be within 0.5 of 26.9     |
diff --git a/rspec-expectations/features/built_in_matchers/change.feature b/rspec-expectations/features/built_in_matchers/change.feature
new file mode 100644
index 0000000..daf970e
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/change.feature
@@ -0,0 +1,66 @@
+Feature: `change` matcher
+
+  The `change` matcher is used to specify that a block of code changes some mutable state.
+  You can specify what will change using either of two forms:
+
+  * `expect { do_something }.to change(object, :attribute)`
+  * `expect { do_something }.to change { object.attribute }`
+
+  You can further qualify the change by chaining `from` and/or `to` or one of `by`, `by_at_most`,
+  `by_at_least`.
+
+  Background:
+    Given a file named "lib/counter.rb" with:
+      """ruby
+      class Counter
+        class << self
+          def increment
+            @count ||= 0
+            @count += 1
+          end
+
+          def count
+            @count ||= 0
+          end
+        end
+      end
+      """
+
+  Scenario: expect change
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "counter"
+
+      RSpec.describe Counter, "#increment" do
+        it "should increment the count" do
+          expect { Counter.increment }.to change{Counter.count}.from(0).to(1)
+        end
+
+        # deliberate failure
+        it "should increment the count by 2" do
+          expect { Counter.increment }.to change{Counter.count}.by(2)
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the output should contain "1 failure"
+    Then the output should contain "expected result to have changed by 2, but was changed by 1"
+
+  Scenario: expect no change
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      require "counter"
+
+      RSpec.describe Counter, "#increment" do
+        it "should not increment the count by 1 (using not_to)" do
+          expect { Counter.increment }.not_to change{Counter.count}
+        end
+
+        it "should not increment the count by 1 (using to_not)" do
+          expect { Counter.increment }.to_not change{Counter.count}
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the output should contain "2 failures"
+    Then the output should contain "expected result not to have changed, but did change from 1 to 2"
diff --git a/rspec-expectations/features/built_in_matchers/comparisons.feature b/rspec-expectations/features/built_in_matchers/comparisons.feature
new file mode 100644
index 0000000..bcc5723
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/comparisons.feature
@@ -0,0 +1,96 @@
+Feature: Comparison matchers
+
+  RSpec provides a number of matchers that are based on Ruby's built-in operators. These
+  can be used for generalized comparison of values. E.g.
+
+    ```ruby
+    expect(9).to be > 6
+    expect(3).to be <= 3
+    expect(1).to be < 6
+    ```
+
+  Scenario: numeric operator matchers
+    Given a file named "numeric_operator_matchers_spec.rb" with:
+      """ruby
+      RSpec.describe 18 do
+        it { is_expected.to be < 20 }
+        it { is_expected.to be > 15 }
+        it { is_expected.to be <= 19 }
+        it { is_expected.to be >= 17 }
+
+        # deliberate failures
+        it { is_expected.to be < 15 }
+        it { is_expected.to be > 20 }
+        it { is_expected.to be <= 17 }
+        it { is_expected.to be >= 19 }
+      end
+      """
+     When I run `rspec numeric_operator_matchers_spec.rb`
+     Then the output should contain "8 examples, 4 failures"
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be < 15 }
+             expected: < 15
+                  got:   18
+      """
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be > 20 }
+             expected: > 20
+                  got:   18
+      """
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be <= 17 }
+             expected: <= 17
+                  got:    18
+      """
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be >= 19 }
+             expected: >= 19
+                  got:    18
+      """
+
+  Scenario: string operator matchers
+    Given a file named "string_operator_matchers_spec.rb" with:
+      """ruby
+      RSpec.describe "Strawberry" do
+        it { is_expected.to be < "Tomato" }
+        it { is_expected.to be > "Apple" }
+        it { is_expected.to be <= "Turnip" }
+        it { is_expected.to be >= "Banana" }
+
+        # deliberate failures
+        it { is_expected.to be < "Cranberry" }
+        it { is_expected.to be > "Zuchini" }
+        it { is_expected.to be <= "Potato" }
+        it { is_expected.to be >= "Tomato" }
+      end
+      """
+     When I run `rspec string_operator_matchers_spec.rb`
+     Then the output should contain "8 examples, 4 failures"
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be < "Cranberry" }
+             expected: < "Cranberry"
+                  got:   "Strawberry"
+      """
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be > "Zuchini" }
+             expected: > "Zuchini"
+                  got:   "Strawberry"
+      """
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be <= "Potato" }
+             expected: <= "Potato"
+                  got:    "Strawberry"
+      """
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to be >= "Tomato" }
+             expected: >= "Tomato"
+                  got:    "Strawberry"
+      """
diff --git a/rspec-expectations/features/built_in_matchers/contain_exactly.feature b/rspec-expectations/features/built_in_matchers/contain_exactly.feature
new file mode 100644
index 0000000..55e2c3c
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/contain_exactly.feature
@@ -0,0 +1,64 @@
+Feature: `contain_exactly` matcher
+
+  The `contain_exactly` matcher provides a way to test arrays against each other in a way
+  that disregards differences in the ordering between the actual and expected array.
+  For example:
+
+    ```ruby
+    expect([1, 2, 3]).to    contain_exactly(2, 3, 1) # pass
+    expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail
+    ```
+
+  This matcher is also available as `match_array`, which expects the expected array to be
+  given as a single array argument rather than as individual splatted elements. The above
+  could also be written as:
+
+    ```ruby
+    expect([1, 2, 3]).to    match_array [2, 3, 1] # pass
+    expect([:a, :c, :b]).to match_array [:a, :c]  # fail
+    ```
+
+  Scenario: Array is expected to contain every value
+    Given a file named "contain_exactly_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe [1, 2, 3] do
+        it { is_expected.to contain_exactly(1, 2, 3) }
+        it { is_expected.to contain_exactly(1, 3, 2) }
+        it { is_expected.to contain_exactly(2, 1, 3) }
+        it { is_expected.to contain_exactly(2, 3, 1) }
+        it { is_expected.to contain_exactly(3, 1, 2) }
+        it { is_expected.to contain_exactly(3, 2, 1) }
+
+        # deliberate failures
+        it { is_expected.to contain_exactly(1, 2, 1) }
+      end
+      """
+     When I run `rspec contain_exactly_matcher_spec.rb`
+     Then the output should contain "7 examples, 1 failure"
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to contain_exactly(1, 2, 1) }
+             expected collection contained:  [1, 1, 2]
+             actual collection contained:    [1, 2, 3]
+             the missing elements were:      [1]
+             the extra elements were:        [3]
+      """
+
+  Scenario: Array is not expected to contain every value
+    Given a file named "contain_exactly_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe [1, 2, 3] do
+        it { is_expected.to_not contain_exactly(1, 2, 3, 4) }
+        it { is_expected.to_not contain_exactly(1, 2) }
+
+        # deliberate failures
+        it { is_expected.to_not contain_exactly(1, 3, 2) }
+      end
+      """
+     When I run `rspec contain_exactly_matcher_spec.rb`
+     Then the output should contain "3 examples, 1 failure"
+      And the output should contain:
+      """
+           Failure/Error: it { is_expected.to_not contain_exactly(1, 3, 2) }
+             expected [1, 2, 3] not to contain exactly 1, 3, and 2
+      """
diff --git a/rspec-expectations/features/built_in_matchers/cover.feature b/rspec-expectations/features/built_in_matchers/cover.feature
new file mode 100644
index 0000000..aa9a538
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/cover.feature
@@ -0,0 +1,47 @@
+ at ruby-1.9
+Feature: `cover` matcher
+
+  Use the cover matcher to specify that a range covers one or more
+  expected objects. This works on any object that responds to #cover?
+  (such as a Range):
+
+    ```ruby
+    expect(1..10).to cover(5)
+    expect(1..10).to cover(4, 6)
+    expect(1..10).not_to cover(11)
+    ```
+
+  Scenario: range usage
+    Given a file named "range_cover_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe (1..10) do
+        it { is_expected.to cover(4) }
+        it { is_expected.to cover(6) }
+        it { is_expected.to cover(8) }
+        it { is_expected.to cover(4, 6) }
+        it { is_expected.to cover(4, 6, 8) }
+        it { is_expected.not_to cover(11) }
+        it { is_expected.not_to cover(11, 12) }
+
+        # deliberate failures
+        it { is_expected.to cover(11) }
+        it { is_expected.not_to cover(4) }
+        it { is_expected.not_to cover(6) }
+        it { is_expected.not_to cover(8) }
+        it { is_expected.not_to cover(4, 6, 8) }
+
+        # both of these should fail since it covers 5 but not 11
+        it { is_expected.to cover(5, 11) }
+        it { is_expected.not_to cover(5, 11) }
+      end
+      """
+    When I run `rspec range_cover_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 14 examples, 7 failures                 |
+      | expected 1..10 to cover 11              |
+      | expected 1..10 not to cover 4           |
+      | expected 1..10 not to cover 6           |
+      | expected 1..10 not to cover 8           |
+      | expected 1..10 not to cover 4, 6, and 8 |
+      | expected 1..10 to cover 5 and 11        |
+      | expected 1..10 not to cover 5 and 11    |
diff --git a/rspec-expectations/features/built_in_matchers/end_with.feature b/rspec-expectations/features/built_in_matchers/end_with.feature
new file mode 100644
index 0000000..0b0d378
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/end_with.feature
@@ -0,0 +1,48 @@
+Feature: `end_with` matcher
+
+  Use the `end_with` matcher to specify that a string or array ends with the expected
+  characters or elements.
+
+    ```ruby
+    expect("this string").to end_with "string"
+    expect("this string").not_to end_with "stringy"
+    expect([0, 1, 2]).to end_with 1, 2
+    ```
+
+  Scenario: string usage
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "this string" do
+        it { is_expected.to end_with "string" }
+        it { is_expected.not_to end_with "stringy" }
+
+        # deliberate failures
+        it { is_expected.not_to end_with "string" }
+        it { is_expected.to end_with "stringy" }
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures                          |
+      | expected "this string" not to end with "string" |
+      | expected "this string" to end with "stringy"    |
+
+  Scenario: array usage
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe [0, 1, 2, 3, 4] do
+        it { is_expected.to end_with 4 }
+        it { is_expected.to end_with 3, 4 }
+        it { is_expected.not_to end_with 3 }
+        it { is_expected.not_to end_with 0, 1, 2, 3, 4, 5 }
+
+        # deliberate failures
+        it { is_expected.not_to end_with 4 }
+        it { is_expected.to end_with 3 }
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain all of these:
+      | 6 examples, 2 failures                     |
+      | expected [0, 1, 2, 3, 4] not to end with 4 |
+      | expected [0, 1, 2, 3, 4] to end with 3     |
diff --git a/rspec-expectations/features/built_in_matchers/equality.feature b/rspec-expectations/features/built_in_matchers/equality.feature
new file mode 100644
index 0000000..9984321
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/equality.feature
@@ -0,0 +1,135 @@
+Feature: Equality matchers
+
+  Ruby exposes several different methods for handling equality:
+
+      a.equal?(b) # object identity - a and b refer to the same object
+      a.eql?(b)   # object equivalence - a and b have the same value
+      a == b      # object equivalence - a and b have the same value with type conversions
+
+  Note that these descriptions are guidelines but are not forced by the language. Any object
+  can implement any of these methods with its own semantics.
+
+  rspec-expectations ships with matchers that align with each of these methods:
+
+    ```ruby
+    expect(a).to equal(b) # passes if a.equal?(b)
+    expect(a).to eql(b)   # passes if a.eql?(b)
+    expect(a).to be == b  # passes if a == b
+    ```
+
+  It also ships with two matchers that have more of a DSL feel to them:
+
+    ```ruby
+    expect(a).to be(b) # passes if a.equal?(b)
+    expect(a).to eq(b) # passes if a == b
+    ```
+
+  Scenario: compare using eq (==)
+    Given a file named "compare_using_eq.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it "is equal to another string of the same value" do
+          expect("this string").to eq("this string")
+        end
+
+        it "is not equal to another string of a different value" do
+          expect("this string").not_to eq("a different string")
+        end
+      end
+
+      RSpec.describe "an integer" do
+        it "is equal to a float of the same value" do
+          expect(5).to eq(5.0)
+        end
+      end
+      """
+    When I run `rspec compare_using_eq.rb`
+    Then the output should contain "3 examples, 0 failures"
+
+  Scenario: compare using ==
+    Given a file named "compare_using_==.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it "is equal to another string of the same value" do
+          expect("this string").to be == "this string"
+        end
+
+        it "is not equal to another string of a different value" do
+          expect("this string").not_to be == "a different string"
+        end
+      end
+
+      RSpec.describe "an integer" do
+        it "is equal to a float of the same value" do
+          expect(5).to be == 5.0
+        end
+      end
+      """
+    When I run `rspec compare_using_==.rb`
+    Then the output should contain "3 examples, 0 failures"
+
+  Scenario: compare using eql (eql?)
+    Given a file named "compare_using_eql.rb" with:
+      """ruby
+      RSpec.describe "an integer" do
+        it "is equal to another integer of the same value" do
+          expect(5).to eql(5)
+        end
+
+        it "is not equal to another integer of a different value" do
+          expect(5).not_to eql(6)
+        end
+
+        it "is not equal to a float of the same value" do
+          expect(5).not_to eql(5.0)
+        end
+
+      end
+      """
+    When I run `rspec compare_using_eql.rb`
+    Then the output should contain "3 examples, 0 failures"
+
+  Scenario: compare using equal (equal?)
+    Given a file named "compare_using_equal.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it "is equal to itself" do
+          string = "this string"
+          expect(string).to equal(string)
+        end
+
+        it "is not equal to another string of the same value" do
+          expect("this string").not_to equal("this string")
+        end
+
+        it "is not equal to another string of a different value" do
+          expect("this string").not_to equal("a different string")
+        end
+
+      end
+      """
+    When I run `rspec compare_using_equal.rb`
+    Then the output should contain "3 examples, 0 failures"
+
+  Scenario: compare using be (equal?)
+    Given a file named "compare_using_be.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it "is equal to itself" do
+          string = "this string"
+          expect(string).to be(string)
+        end
+
+        it "is not equal to another string of the same value" do
+          expect("this string").not_to be("this string")
+        end
+
+        it "is not equal to another string of a different value" do
+          expect("this string").not_to be("a different string")
+        end
+
+      end
+      """
+    When I run `rspec compare_using_be.rb`
+    Then the output should contain "3 examples, 0 failures"
+
diff --git a/rspec-expectations/features/built_in_matchers/exist.feature b/rspec-expectations/features/built_in_matchers/exist.feature
new file mode 100644
index 0000000..09bfabb
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/exist.feature
@@ -0,0 +1,44 @@
+Feature: `exist` matcher
+
+  The exist matcher is used to specify that something exists (as indicated by #exist? or #exists?):
+
+    ```ruby
+    expect(obj).to exist # passes if obj.exist? or obj.exists?
+    ```
+
+  Scenario: basic usage
+    Given a file named "exist_matcher_spec.rb" with:
+      """ruby
+      class Planet
+        attr_reader :name
+
+        def initialize(name)
+          @name = name
+        end
+
+        def inspect
+          "<Planet: #{name}>"
+        end
+
+        def exist? # also works with exists?
+          %w[Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune].include?(name)
+        end
+      end
+
+      RSpec.describe "Earth" do
+        let(:earth) { Planet.new("Earth") }
+        specify { expect(earth).to exist }
+        specify { expect(earth).not_to exist } # deliberate failure
+      end
+
+      RSpec.describe "Tatooine" do
+        let(:tatooine) { Planet.new("Tatooine") }
+        specify { expect(tatooine).to exist } # deliberate failure
+        specify { expect(tatooine).not_to exist }
+      end
+      """
+    When I run `rspec exist_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures                |
+      | expected <Planet: Earth> not to exist |
+      | expected <Planet: Tatooine> to exist  |
diff --git a/rspec-expectations/features/built_in_matchers/have_attributes.feature b/rspec-expectations/features/built_in_matchers/have_attributes.feature
new file mode 100644
index 0000000..d879a39
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/have_attributes.feature
@@ -0,0 +1,47 @@
+Feature: `have_attributes` matcher
+
+  Use the have_attributes matcher to specify that
+  an object's attributes match the expected attributes:
+
+    ```ruby
+    Person = Struct.new(:name, :age)
+    person = Person.new("Jim", 32)
+
+    expect(person).to have_attributes(:name => "Jim", :age => 32)
+    expect(person).to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) )
+    ```
+
+  The matcher will fail if actual doesn't respond to any of the expected attributes:
+
+    ```ruby
+    expect(person).to have_attributes(:name => "Jim", :color => 'red')
+    ```
+
+  Scenario: basic usage
+    Given a file named "basic_have_attributes_matcher_spec.rb" with:
+      """ruby
+      Person = Struct.new(:name, :age)
+
+      RSpec.describe Person.new("Jim", 32) do
+        it { is_expected.to have_attributes(:name => "Jim") }
+        it { is_expected.to have_attributes(:name => a_string_starting_with("J") ) }
+        it { is_expected.to have_attributes(:age => 32) }
+        it { is_expected.to have_attributes(:age => (a_value > 30) ) }
+        it { is_expected.to have_attributes(:name => "Jim", :age => 32) }
+        it { is_expected.to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) ) }
+        it { is_expected.not_to have_attributes(:name => "Bob") }
+        it { is_expected.not_to have_attributes(:age => 10) }
+        it { is_expected.not_to have_attributes(:age => (a_value < 30) ) }
+
+        # deliberate failures
+        it { is_expected.to have_attributes(:name => "Bob") }
+        it { is_expected.to have_attributes(:age => 10) }
+
+        # fails if any of the attributes don't match
+        it { is_expected.to have_attributes(:name => "Bob", :age => 32) }
+        it { is_expected.to have_attributes(:name => "Jim", :age => 10) }
+        it { is_expected.to have_attributes(:name => "Bob", :age => 10) }
+      end
+      """
+    When I run `rspec basic_have_attributes_matcher_spec.rb`
+    Then the output should contain "14 examples, 5 failures"
diff --git a/rspec-expectations/features/built_in_matchers/include.feature b/rspec-expectations/features/built_in_matchers/include.feature
new file mode 100644
index 0000000..b459606
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/include.feature
@@ -0,0 +1,123 @@
+Feature: `include` matcher
+
+  Use the include matcher to specify that a collection includes one or more expected objects.
+  This works on any object that responds to #include?  (such as a string or array):
+
+    ```ruby
+    expect("a string").to include("a")
+    expect("a string").to include("str")
+    expect("a string").to include("str", "g")
+    expect("a string").not_to include("foo")
+
+    expect([1, 2]).to include(1)
+    expect([1, 2]).to include(1, 2)
+    expect([1, 2]).not_to include(17)
+    ```
+
+  The matcher also provides flexible handling for hashes:
+
+    ```ruby
+    expect(:a => 1, :b => 2).to include(:a)
+    expect(:a => 1, :b => 2).to include(:a, :b)
+    expect(:a => 1, :b => 2).to include(:a => 1)
+    expect(:a => 1, :b => 2).to include(:b => 2, :a => 1)
+    expect(:a => 1, :b => 2).not_to include(:c)
+    expect(:a => 1, :b => 2).not_to include(:a => 2)
+    expect(:a => 1, :b => 2).not_to include(:c => 3)
+    ```
+
+  Scenario: array usage
+    Given a file named "array_include_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe [1, 3, 7] do
+        it { is_expected.to include(1) }
+        it { is_expected.to include(3) }
+        it { is_expected.to include(7) }
+        it { is_expected.to include(1, 7) }
+        it { is_expected.to include(1, 3, 7) }
+        it { is_expected.not_to include(17) }
+        it { is_expected.not_to include(43, 100) }
+
+        # deliberate failures
+        it { is_expected.to include(4) }
+        it { is_expected.not_to include(1) }
+        it { is_expected.not_to include(3) }
+        it { is_expected.not_to include(7) }
+        it { is_expected.not_to include(1, 3, 7) }
+
+        # both of these should fail since it includes 1 but not 9
+        it { is_expected.to include(1, 9) }
+        it { is_expected.not_to include(1, 9) }
+      end
+      """
+    When I run `rspec array_include_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 14 examples, 7 failures                       |
+      | expected [1, 3, 7] to include 4               |
+      | expected [1, 3, 7] not to include 1           |
+      | expected [1, 3, 7] not to include 3           |
+      | expected [1, 3, 7] not to include 7           |
+      | expected [1, 3, 7] not to include 1, 3, and 7 |
+      | expected [1, 3, 7] to include 1 and 9         |
+      | expected [1, 3, 7] not to include 1 and 9     |
+
+  Scenario: string usage
+    Given a file named "string_include_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it { is_expected.to include("str") }
+        it { is_expected.to include("a", "str", "ng") }
+        it { is_expected.not_to include("foo") }
+        it { is_expected.not_to include("foo", "bar") }
+
+        # deliberate failures
+        it { is_expected.to include("foo") }
+        it { is_expected.not_to include("str") }
+        it { is_expected.to include("str", "foo") }
+        it { is_expected.not_to include("str", "foo") }
+      end
+      """
+    When I run `rspec string_include_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures                             |
+      | expected "a string" to include "foo"               |
+      | expected "a string" not to include "str"           |
+      | expected "a string" to include "str" and "foo"     |
+      | expected "a string" not to include "str" and "foo" |
+
+  Scenario: hash usage
+    Given a file named "hash_include_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe :a => 7, :b => 5 do
+        it { is_expected.to include(:a) }
+        it { is_expected.to include(:b, :a) }
+        it { is_expected.to include(:a => 7) }
+        it { is_expected.to include(:b => 5, :a => 7) }
+        it { is_expected.not_to include(:c) }
+        it { is_expected.not_to include(:c, :d) }
+        it { is_expected.not_to include(:d => 2) }
+        it { is_expected.not_to include(:a => 5) }
+        it { is_expected.not_to include(:b => 7, :a => 5) }
+
+        # deliberate failures
+        it { is_expected.not_to include(:a) }
+        it { is_expected.not_to include(:b, :a) }
+        it { is_expected.not_to include(:a => 7) }
+        it { is_expected.not_to include(:a => 7, :b => 5) }
+        it { is_expected.to include(:c) }
+        it { is_expected.to include(:c, :d) }
+        it { is_expected.to include(:d => 2) }
+        it { is_expected.to include(:a => 5) }
+        it { is_expected.to include(:a => 5, :b => 7) }
+
+        # Mixed cases--the hash includes one but not the other.
+        # All 4 of these cases should fail.
+        it { is_expected.to include(:a, :d) }
+        it { is_expected.not_to include(:a, :d) }
+        it { is_expected.to include(:a => 7, :d => 3) }
+        it { is_expected.not_to include(:a => 7, :d => 3) }
+      end
+      """
+    When I run `rspec hash_include_matcher_spec.rb`
+    Then the output should contain "13 failure"
+
diff --git a/rspec-expectations/features/built_in_matchers/match.feature b/rspec-expectations/features/built_in_matchers/match.feature
new file mode 100644
index 0000000..da72beb
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/match.feature
@@ -0,0 +1,49 @@
+Feature: `match` matcher
+
+  The match matcher calls `#match` on the object, passing if `#match` returns a truthy (not
+  `false` or `nil`) value.  Regexp and String both provide a `#match` method.
+
+    ```ruby
+    expect("a string").to match(/str/) # passes
+    expect("a string").to match(/foo/) # fails
+    expect(/foo/).to match("food")     # passes
+    expect(/foo/).to match("drinks")   # fails
+    ```
+
+  You can also use this matcher to match nested data structures when composing matchers.
+
+  Scenario: string usage
+    Given a file named "string_match_spec.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it { is_expected.to match(/str/) }
+        it { is_expected.not_to match(/foo/) }
+
+        # deliberate failures
+        it { is_expected.not_to match(/str/) }
+        it { is_expected.to match(/foo/) }
+      end
+      """
+    When I run `rspec string_match_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures                 |
+      | expected "a string" not to match /str/ |
+      | expected "a string" to match /foo/     |
+
+  Scenario: regular expression usage
+    Given a file named "regexp_match_spec.rb" with:
+      """ruby
+      RSpec.describe /foo/ do
+        it { is_expected.to match("food") }
+        it { is_expected.not_to match("drinks") }
+
+        # deliberate failures
+        it { is_expected.not_to match("food") }
+        it { is_expected.to match("drinks") }
+      end
+      """
+    When I run `rspec regexp_match_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures             |
+      | expected /foo/ not to match "food" |
+      | expected /foo/ to match "drinks"   |
diff --git a/rspec-expectations/features/built_in_matchers/output.feature b/rspec-expectations/features/built_in_matchers/output.feature
new file mode 100644
index 0000000..0bfb6a0
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/output.feature
@@ -0,0 +1,131 @@
+Feature: `output` matcher
+
+  The `output` matcher provides a way to assert that the has emitted content to either
+  `$stdout` or `$stderr`.
+
+  With no arg, passes if the block outputs `to_stdout` or `to_stderr`. With a string, passes
+  if the blocks outputs that specific string `to_stdout` or `to_stderr`. With a regexp or
+  matcher, passes if the blocks outputs a string `to_stdout` or `to_stderr` that matches.
+
+  Note: `to_stdout` and `to_stderr` work by temporarily replacing `$stdout` or `$stderr`, so
+  they're not able to intercept stream output that explicitly uses `STDOUT`/`STDERR` or that
+  uses a reference to `$stdout`/`$stderr` that was stored before the matcher is used.
+
+  To capture output from any spawned subprocess as well, use `to_stdout_from_any_process`
+  or `to_stderr_from_any_process`. Output from any process that inherits the main process's
+  corresponding standard stream will be captured.
+
+  Note: `to_stdout_from_any_process` and `to_stderr_from_any_process` use tempfiles to
+  capture output, and are thus significantly (~30x) slower than `to_stdout` and `to_stderr`.
+
+  Scenario: output_to_stdout matcher
+    Given a file named "output_to_stdout_spec.rb" with:
+      """ruby
+      RSpec.describe "output.to_stdout matcher" do
+        specify { expect { print('foo') }.to output.to_stdout }
+        specify { expect { print('foo') }.to output('foo').to_stdout }
+        specify { expect { print('foo') }.to output(/foo/).to_stdout }
+        specify { expect { }.to_not output.to_stdout }
+        specify { expect { print('foo') }.to_not output('bar').to_stdout }
+        specify { expect { print('foo') }.to_not output(/bar/).to_stdout }
+
+        # deliberate failures
+        specify { expect { }.to output.to_stdout }
+        specify { expect { }.to output('foo').to_stdout }
+        specify { expect { print('foo') }.to_not output.to_stdout }
+        specify { expect { print('foo') }.to output('bar').to_stdout }
+        specify { expect { print('foo') }.to output(/bar/).to_stdout }
+      end
+      """
+    When I run `rspec output_to_stdout_spec.rb`
+    Then the output should contain all of these:
+      | 11 examples, 5 failures                                      |
+      | expected block to output to stdout, but did not              |
+      | expected block to not output to stdout, but output "foo"     |
+      | expected block to output "bar" to stdout, but output "foo"   |
+      | expected block to output "foo" to stdout, but output nothing |
+      | expected block to output /bar/ to stdout, but output "foo"   |
+
+  Scenario: output_to_stderr matcher
+    Given a file named "output_to_stderr.rb" with:
+      """ruby
+      RSpec.describe "output_to_stderr matcher" do
+        specify { expect { warn('foo') }.to output.to_stderr }
+        specify { expect { warn('foo') }.to output("foo\n").to_stderr }
+        specify { expect { warn('foo') }.to output(/foo/).to_stderr }
+        specify { expect { }.to_not output.to_stderr }
+        specify { expect { warn('foo') }.to_not output('bar').to_stderr }
+        specify { expect { warn('foo') }.to_not output(/bar/).to_stderr }
+
+        # deliberate failures
+        specify { expect { }.to output.to_stderr }
+        specify { expect { }.to output('foo').to_stderr }
+        specify { expect { warn('foo') }.to_not output.to_stderr }
+        specify { expect { warn('foo') }.to output('bar').to_stderr }
+        specify { expect { warn('foo') }.to output(/bar/).to_stderr }
+      end
+      """
+    When I run `rspec output_to_stderr.rb`
+    Then the output should contain all of these:
+      | 11 examples, 5 failures                                      |
+      | expected block to output to stderr, but did not              |
+      | expected block to not output to stderr, but output "foo      |
+      | expected block to output "bar" to stderr, but output "foo\n" |
+      | expected block to output "foo" to stderr, but output nothing |
+      | expected block to output /bar/ to stderr, but output "foo\n" |
+
+  Scenario: output_to_stdout_from_any_process matcher
+    Given a file named "output_to_stdout_from_any_process_spec.rb" with:
+      """ruby
+      RSpec.describe "output.to_stdout_from_any_process matcher" do
+        specify { expect { system('printf foo') }.to output.to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to output("foo").to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to output(/foo/).to_stdout_from_any_process }
+        specify { expect { }.to_not output.to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to_not output("bar").to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to_not output(/bar/).to_stdout_from_any_process }
+
+        # deliberate failures
+        specify { expect { }.to output.to_stdout_from_any_process }
+        specify { expect { }.to output('foo').to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to_not output.to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to output('bar').to_stdout_from_any_process }
+        specify { expect { system('printf foo') }.to output(/bar/).to_stdout_from_any_process }
+      end
+      """
+    When I run `rspec output_to_stdout_from_any_process_spec.rb`
+    Then the output should contain all of these:
+      | 11 examples, 5 failures                                      |
+      | expected block to output to stdout, but did not              |
+      | expected block to not output to stdout, but output "foo"     |
+      | expected block to output "bar" to stdout, but output "foo"   |
+      | expected block to output "foo" to stdout, but output nothing |
+      | expected block to output /bar/ to stdout, but output "foo"   |
+
+  Scenario: output_to_stderr_from_any_process matcher
+    Given a file named "output_to_stderr_from_any_process_spec.rb" with:
+      """ruby
+      RSpec.describe "output.to_stderr_from_any_process matcher" do
+        specify { expect { system('printf foo 1>&2') }.to output.to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to output("foo").to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to output(/foo/).to_stderr_from_any_process }
+        specify { expect { }.to_not output.to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to_not output("bar").to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to_not output(/bar/).to_stderr_from_any_process }
+
+        # deliberate failures
+        specify { expect { }.to output.to_stderr_from_any_process }
+        specify { expect { }.to output('foo').to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to_not output.to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to output('bar').to_stderr_from_any_process }
+        specify { expect { system('printf foo 1>&2') }.to output(/bar/).to_stderr_from_any_process }
+      end
+      """
+    When I run `rspec output_to_stderr_from_any_process_spec.rb`
+    Then the output should contain all of these:
+      | 11 examples, 5 failures                                      |
+      | expected block to output to stderr, but did not              |
+      | expected block to not output to stderr, but output "foo"     |
+      | expected block to output "bar" to stderr, but output "foo"   |
+      | expected block to output "foo" to stderr, but output nothing |
+      | expected block to output /bar/ to stderr, but output "foo"   |
diff --git a/rspec-expectations/features/built_in_matchers/predicates.feature b/rspec-expectations/features/built_in_matchers/predicates.feature
new file mode 100644
index 0000000..64061bd
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/predicates.feature
@@ -0,0 +1,181 @@
+Feature: Predicate matchers
+
+  Ruby objects commonly provide predicate methods:
+
+    ```ruby
+    7.zero?                  # => false
+    0.zero?                  # => true
+    [1].empty?               # => false
+    [].empty?                # => true
+    { :a => 5 }.has_key?(:b) # => false
+    { :b => 5 }.has_key?(:b) # => true
+    ```
+
+  You could use a basic equality matcher to set expectations on these:
+
+    ```ruby
+    expect(7.zero?).to eq true # fails with "expected true, got false (using ==)"
+    ```
+
+  ...but RSpec provides dynamic predicate matchers that are more readable and provide
+  better failure output.
+
+  For any predicate method, RSpec gives you a corresponding matcher. Simply prefix the
+  method with `be_` and remove the question mark. Examples:
+
+    ```ruby
+    expect(7).not_to be_zero       # calls 7.zero?
+    expect([]).to be_empty         # calls [].empty?
+    expect(x).to be_multiple_of(3) # calls x.multiple_of?(3)
+    ```
+
+  Alternately, for a predicate method that begins with `has_` like `Hash#has_key?`, RSpec allows
+  you to use an alternate form since `be_has_key` makes no sense.
+
+    ```ruby
+    expect(hash).to have_key(:foo)       # calls hash.has_key?(:foo)
+    expect(array).not_to have_odd_values # calls array.has_odd_values?
+    ```
+
+  In either case, RSpec provides nice, clear error messages, such as:
+
+    `expected zero? to return true, got false`
+
+  Calling private methods will also fail:
+
+    `expected private_method? to return true but it's a private method`
+
+  Any arguments passed to the matcher will be passed on to the predicate method.
+
+  Scenario: should be_zero (based on Fixnum#zero?)
+    Given a file named "should_be_zero_spec.rb" with:
+      """ruby
+      RSpec.describe 0 do
+        it { is_expected.to be_zero }
+      end
+
+      RSpec.describe 7 do
+        it { is_expected.to be_zero } # deliberate failure
+      end
+      """
+    When I run `rspec should_be_zero_spec.rb`
+    Then the output should contain "2 examples, 1 failure"
+     And the output should contain "expected `7.zero?` to return true, got false"
+
+  Scenario: should_not be_empty (based on Array#empty?)
+    Given a file named "should_not_be_empty_spec.rb" with:
+      """ruby
+      RSpec.describe [1, 2, 3] do
+        it { is_expected.not_to be_empty }
+      end
+
+      RSpec.describe [] do
+        it { is_expected.not_to be_empty } # deliberate failure
+      end
+      """
+    When I run `rspec should_not_be_empty_spec.rb`
+    Then the output should contain "2 examples, 1 failure"
+     And the output should contain "expected `[].empty?` to return false, got true"
+
+   Scenario: should have_key (based on Hash#has_key?)
+    Given a file named "should_have_key_spec.rb" with:
+      """ruby
+      RSpec.describe Hash do
+        subject { { :foo => 7 } }
+        it { is_expected.to have_key(:foo) }
+        it { is_expected.to have_key(:bar) } # deliberate failure
+      end
+      """
+    When I run `rspec should_have_key_spec.rb`
+    Then the output should contain "2 examples, 1 failure"
+     And the output should contain "expected #has_key?(:bar) to return true, got false"
+
+   Scenario: should_not have_all_string_keys (based on custom #has_all_string_keys? method)
+     Given a file named "should_not_have_all_string_keys_spec.rb" with:
+       """ruby
+       class Hash
+         def has_all_string_keys?
+           keys.all? { |k| String === k }
+         end
+       end
+
+       RSpec.describe Hash do
+         context 'with symbol keys' do
+           subject { { :foo => 7, :bar => 5 } }
+           it { is_expected.not_to have_all_string_keys }
+         end
+
+         context 'with string keys' do
+           subject { { 'foo' => 7, 'bar' => 5 } }
+           it { is_expected.not_to have_all_string_keys } # deliberate failure
+         end
+       end
+       """
+     When I run `rspec should_not_have_all_string_keys_spec.rb`
+     Then the output should contain "2 examples, 1 failure"
+      And the output should contain "expected #has_all_string_keys? to return false, got true"
+
+   Scenario: matcher arguments are passed on to the predicate method
+     Given a file named "predicate_matcher_argument_spec.rb" with:
+       """ruby
+       class Fixnum
+         def multiple_of?(x)
+           (self % x).zero?
+         end
+       end
+
+       RSpec.describe 12 do
+         it { is_expected.to be_multiple_of(3) }
+         it { is_expected.not_to be_multiple_of(7) }
+
+         # deliberate failures
+         it { is_expected.not_to be_multiple_of(4) }
+         it { is_expected.to be_multiple_of(5) }
+       end
+       """
+     When I run `rspec predicate_matcher_argument_spec.rb`
+     Then the output should contain "4 examples, 2 failures"
+      And the output should contain "expected `12.multiple_of?(4)` to return false, got true"
+      And the output should contain "expected `12.multiple_of?(5)` to return true, got false"
+
+    Scenario: calling private method with be_predicate causes error
+      Given a file named "attempting_to_match_private_method_spec.rb" with:
+       """ruby
+       class WithPrivateMethods
+         def secret?
+           true
+         end
+         private :secret?
+       end
+
+       RSpec.describe 'private methods' do
+         subject { WithPrivateMethods.new }
+
+         # deliberate failure
+         it { is_expected.to be_secret }
+       end
+       """
+     When I run `rspec attempting_to_match_private_method_spec.rb`
+     Then the output should contain "1 example, 1 failure"
+     And the output should contain "`secret?` is a private method"
+
+    Scenario: calling private method with have_predicate causes error
+      Given a file named "attempting_to_match_private_method_spec.rb" with:
+       """ruby
+       class WithPrivateMethods
+         def has_secret?
+           true
+         end
+         private :has_secret?
+       end
+
+       RSpec.describe 'private methods' do
+         subject { WithPrivateMethods.new }
+
+         # deliberate failure
+         it { is_expected.to have_secret }
+       end
+       """
+     When I run `rspec attempting_to_match_private_method_spec.rb`
+     Then the output should contain "1 example, 1 failure"
+     And the output should contain "`has_secret?` is a private method"
diff --git a/rspec-expectations/features/built_in_matchers/raise_error.feature b/rspec-expectations/features/built_in_matchers/raise_error.feature
new file mode 100644
index 0000000..953a360
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/raise_error.feature
@@ -0,0 +1,144 @@
+Feature: `raise_error` matcher
+
+  Use the `raise_error` matcher to specify that a block of code raises an error. The most
+  basic form passes if any error is thrown:
+
+    ```ruby
+    expect { raise StandardError }.to raise_error
+    ```
+
+  You can use `raise_exception` instead if you prefer that wording:
+
+    ```ruby
+    expect { 3 / 0 }.to raise_exception
+    ```
+
+  `raise_error` and `raise_exception` are functionally interchangeable, so use the one that
+  makes the most sense to you in any given context.
+
+  In addition to the basic form, above, there are a number of ways to specify details of an
+  error/exception:
+
+    ```ruby
+    expect { raise "oops" }.to raise_error
+    expect { raise "oops" }.to raise_error(RuntimeError)
+    expect { raise "oops" }.to raise_error("oops")
+    expect { raise "oops" }.to raise_error(/op/)
+    expect { raise "oops" }.to raise_error(RuntimeError, "oops")
+    expect { raise "oops" }.to raise_error(RuntimeError, /op/)
+    ```
+
+  Scenario: expect any error
+    Given a file named "example_spec" with:
+      """
+      RSpec.describe "calling a missing method" do
+        it "raises" do
+          expect { Object.new.foo }.to raise_error
+        end
+      end
+      """
+    When I run `rspec example_spec`
+    Then the example should pass
+
+  Scenario: expect specific error
+    Given a file named "example_spec" with:
+      """
+      RSpec.describe "calling a missing method" do
+        it "raises" do
+          expect { Object.new.foo }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec example_spec`
+    Then the example should pass
+
+  Scenario: match message with a string
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "matching error message with string" do
+        it "matches the error message" do
+          expect { raise StandardError, 'this message exactly'}.
+            to raise_error('this message exactly')
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the example should pass
+
+  Scenario: match message with a regexp
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "matching error message with regex" do
+        it "matches the error message" do
+          expect { raise StandardError, "my message" }.
+            to raise_error(/my mess/)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the example should pass
+
+  Scenario: matching message with `with_message`
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "matching error message with regex" do
+        it "matches the error message" do
+          expect { raise StandardError, "my message" }.
+            to raise_error.with_message(/my mess/)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the example should pass
+
+  Scenario: match class + message with string
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "matching error message with string" do
+        it "matches the error message" do
+          expect { raise StandardError, 'this message exactly'}.
+            to raise_error(StandardError, 'this message exactly')
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the example should pass
+
+  Scenario: match class + message with regexp
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "matching error message with regex" do
+        it "matches the error message" do
+          expect { raise StandardError, "my message" }.
+            to raise_error(StandardError, /my mess/)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the example should pass
+
+  Scenario: set expectations on error object passed to block
+    Given a file named "example_spec" with:
+      """
+      RSpec.describe "#foo" do
+        it "raises NameError" do
+          expect { Object.new.foo }.to raise_error { |error|
+            expect(error).to be_a(NameError)
+          }
+        end
+      end
+      """
+      When I run `rspec example_spec`
+      Then the example should pass
+
+  Scenario: expect no error at all
+    Given a file named "example_spec" with:
+      """
+      RSpec.describe "#to_s" do
+        it "does not raise" do
+          expect { Object.new.to_s }.not_to raise_error
+        end
+      end
+      """
+    When I run `rspec example_spec`
+    Then the example should pass
diff --git a/rspec-expectations/features/built_in_matchers/respond_to.feature b/rspec-expectations/features/built_in_matchers/respond_to.feature
new file mode 100644
index 0000000..3ae2a4d
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/respond_to.feature
@@ -0,0 +1,83 @@
+Feature: `respond_to` matcher
+
+  Use the respond_to matcher to specify details of an object's interface.  In its most basic form:
+
+    ```ruby
+    expect(obj).to respond_to(:foo) # pass if obj.respond_to?(:foo)
+    ```
+
+  You can specify that an object responds to multiple messages in a single statement with
+  multiple arguments passed to the matcher:
+
+    ```ruby
+    expect(obj).to respond_to(:foo, :bar) # passes if obj.respond_to?(:foo) && obj.respond_to?(:bar)
+    ```
+
+  If the number of arguments accepted by the method is important to you, you can specify
+  that as well:
+
+    ```ruby
+    expect(obj).to respond_to(:foo).with(1).argument
+    expect(obj).to respond_to(:bar).with(2).arguments
+    ```
+
+  Note that this matcher relies entirely upon #respond_to?.  If an object dynamically responds
+  to a message via #method_missing, but does not indicate this via #respond_to?, then this
+  matcher will give you false results.
+
+  Scenario: basic usage
+    Given a file named "respond_to_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe "a string" do
+        it { is_expected.to respond_to(:length) }
+        it { is_expected.to respond_to(:hash, :class, :to_s) }
+        it { is_expected.not_to respond_to(:to_model) }
+        it { is_expected.not_to respond_to(:compact, :flatten) }
+
+        # deliberate failures
+        it { is_expected.to respond_to(:to_model) }
+        it { is_expected.to respond_to(:compact, :flatten) }
+        it { is_expected.not_to respond_to(:length) }
+        it { is_expected.not_to respond_to(:hash, :class, :to_s) }
+
+        # mixed examples--String responds to :length but not :flatten
+        # both specs should fail
+        it { is_expected.to respond_to(:length, :flatten) }
+        it { is_expected.not_to respond_to(:length, :flatten) }
+      end
+      """
+    When I run `rspec respond_to_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 10 examples, 6 failures                                    |
+      | expected "a string" to respond to :to_model                |
+      | expected "a string" to respond to :compact, :flatten       |
+      | expected "a string" not to respond to :length              |
+      | expected "a string" not to respond to :hash, :class, :to_s |
+      | expected "a string" to respond to :flatten                 |
+      | expected "a string" not to respond to :length              |
+
+  Scenario: specify arguments
+    Given a file named "respond_to_matcher_argument_checking_spec.rb" with:
+      """ruby
+      RSpec.describe 7 do
+        it { is_expected.to respond_to(:zero?).with(0).arguments }
+        it { is_expected.not_to respond_to(:zero?).with(1).argument }
+
+        it { is_expected.to respond_to(:between?).with(2).arguments }
+        it { is_expected.not_to respond_to(:between?).with(7).arguments }
+
+        # deliberate failures
+        it { is_expected.to respond_to(:zero?).with(1).argument }
+        it { is_expected.not_to respond_to(:zero?).with(0).arguments }
+
+        it { is_expected.to respond_to(:between?).with(7).arguments }
+        it { is_expected.not_to respond_to(:between?).with(2).arguments }
+      end
+      """
+    When I run `rspec respond_to_matcher_argument_checking_spec.rb`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures                                  |
+      | expected 7 to respond to :zero? with 1 argument         |
+      | expected 7 not to respond to :zero? with 0 arguments    |
+      | expected 7 to respond to :between? with 7 arguments     |
+      | expected 7 not to respond to :between? with 2 arguments |
diff --git a/rspec-expectations/features/built_in_matchers/satisfy.feature b/rspec-expectations/features/built_in_matchers/satisfy.feature
new file mode 100644
index 0000000..c04f13e
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/satisfy.feature
@@ -0,0 +1,32 @@
+Feature: `satisfy` matcher
+
+  The satisfy matcher is extremely flexible and can handle almost anything you want to
+  specify. It passes if the block you provide returns true:
+
+    ```ruby
+    expect(10).to satisfy { |v| v % 5 == 0 }
+    expect(7).not_to satisfy { |v| v % 5 == 0 }
+    ```
+
+  This flexibility comes at a cost, however: the failure message ("expected [actual] to satisfy
+  block") is not very descriptive or helpful.  You will usually be better served by using one of
+  the other built-in matchers, or writing a custom matcher.
+
+  Scenario: basic usage
+    Given a file named "satisfy_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe 10 do
+        it { is_expected.to satisfy { |v| v > 5 } }
+        it { is_expected.not_to satisfy { |v| v > 15 } }
+
+        # deliberate failures
+        it { is_expected.not_to satisfy { |v| v > 5 } }
+        it { is_expected.to satisfy { |v| v > 15 } }
+      end
+      """
+    When I run `rspec satisfy_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures           |
+      | expected 10 not to satisfy block |
+      | expected 10 to satisfy block     |
+
diff --git a/rspec-expectations/features/built_in_matchers/start_with.feature b/rspec-expectations/features/built_in_matchers/start_with.feature
new file mode 100644
index 0000000..f49ed26
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/start_with.feature
@@ -0,0 +1,48 @@
+Feature: `start_with` matcher
+
+  Use the `start_with` matcher to specify that a string or array starts with the expected
+  characters or elements.
+
+    ```ruby
+    expect("this string").to start_with("this")
+    expect("this string").not_to start_with("that")
+    expect([0,1,2]).to start_with(0, 1)
+    ```
+
+  Scenario: with a string
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "this string" do
+        it { is_expected.to start_with "this" }
+        it { is_expected.not_to start_with "that" }
+
+        # deliberate failures
+        it { is_expected.not_to start_with "this" }
+        it { is_expected.to start_with "that" }
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures                          |
+      | expected "this string" not to start with "this" |
+      | expected "this string" to start with "that"     |
+
+  Scenario: with an array
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe [0, 1, 2, 3, 4] do
+        it { is_expected.to start_with 0 }
+        it { is_expected.to start_with(0, 1)}
+        it { is_expected.not_to start_with(2) }
+        it { is_expected.not_to start_with(0, 1, 2, 3, 4, 5) }
+
+        # deliberate failures
+        it { is_expected.not_to start_with 0 }
+        it { is_expected.to start_with 3 }
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain all of these:
+      | 6 examples, 2 failures                       |
+      | expected [0, 1, 2, 3, 4] not to start with 0 |
+      | expected [0, 1, 2, 3, 4] to start with 3     |
diff --git a/rspec-expectations/features/built_in_matchers/throw_symbol.feature b/rspec-expectations/features/built_in_matchers/throw_symbol.feature
new file mode 100644
index 0000000..26589b7
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/throw_symbol.feature
@@ -0,0 +1,90 @@
+Feature: `throw_symbol` matcher
+
+  The throw_symbol matcher is used to specify that a block of code throws a symbol. The most
+  basic form passes if any symbol is thrown:
+
+    ```ruby
+    expect { throw :foo }.to throw_symbol
+    ```
+
+  You'll often want to specify that a particular symbol is thrown:
+
+    ```ruby
+    expect { throw :foo }.to throw_symbol(:foo)
+    ```
+
+  If you care about the additional argument given to throw, you can specify that as well:
+
+    ```ruby
+    expect { throw :foo, 7 }.to throw_symbol(:foo, 7)
+    ```
+
+  Scenario: basic usage
+    Given a file named "throw_symbol_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe "throw" do
+        specify { expect { throw :foo    }.to     throw_symbol }
+        specify { expect { throw :bar, 7 }.to     throw_symbol }
+        specify { expect { 5 + 5         }.not_to throw_symbol }
+
+        # deliberate failures
+        specify { expect { throw :foo    }.not_to throw_symbol }
+        specify { expect { throw :bar, 7 }.not_to throw_symbol }
+        specify { expect { 5 + 5         }.to     throw_symbol }
+      end
+      """
+    When I run `rspec throw_symbol_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 6 examples, 3 failures                      |
+      | expected no Symbol to be thrown, got :foo   |
+      | expected no Symbol to be thrown, got :bar   |
+      | expected a Symbol to be thrown, got nothing |
+
+  Scenario: specify thrown symbol
+    Given a file named "throw_symbol_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe "throw symbol" do
+        specify { expect { throw :foo    }.to     throw_symbol(:foo) }
+        specify { expect { throw :foo, 7 }.to     throw_symbol(:foo) }
+        specify { expect { 5 + 5         }.not_to throw_symbol(:foo) }
+        specify { expect { throw :bar    }.not_to throw_symbol(:foo) }
+
+        # deliberate failures
+        specify { expect { throw :foo    }.not_to throw_symbol(:foo) }
+        specify { expect { throw :foo, 7 }.not_to throw_symbol(:foo) }
+        specify { expect { 5 + 5         }.to     throw_symbol(:foo) }
+        specify { expect { throw :bar    }.to     throw_symbol(:foo) }
+      end
+      """
+    When I run `rspec throw_symbol_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures                          |
+      | expected :foo not to be thrown, got :foo        |
+      | expected :foo not to be thrown, got :foo with 7 |
+      | expected :foo to be thrown, got nothing         |
+      | expected :foo to be thrown, got :bar            |
+
+  Scenario: specify thrown symbol and argument
+    Given a file named "throw_symbol_argument_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe "throw symbol with argument" do
+        specify { expect { throw :foo, 7 }.to     throw_symbol(:foo, 7) }
+        specify { expect { throw :foo, 8 }.not_to throw_symbol(:foo, 7) }
+        specify { expect { throw :bar, 7 }.not_to throw_symbol(:foo, 7) }
+        specify { expect { throw :foo    }.not_to throw_symbol(:foo, 7) }
+
+        # deliberate failures
+        specify { expect { throw :foo, 7 }.not_to throw_symbol(:foo, 7) }
+        specify { expect { throw :foo, 8 }.to     throw_symbol(:foo, 7) }
+        specify { expect { throw :bar, 7 }.to     throw_symbol(:foo, 7) }
+        specify { expect { throw :foo    }.to     throw_symbol(:foo, 7) }
+      end
+      """
+    When I run `rspec throw_symbol_argument_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures                                       |
+      | expected :foo with 7 not to be thrown, got :foo with 7       |
+      | expected :foo with 7 to be thrown, got :foo with 8           |
+      | expected :foo with 7 to be thrown, got :bar                  |
+      | expected :foo with 7 to be thrown, got :foo with no argument |
+
diff --git a/rspec-expectations/features/built_in_matchers/types.feature b/rspec-expectations/features/built_in_matchers/types.feature
new file mode 100644
index 0000000..8a56571
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/types.feature
@@ -0,0 +1,116 @@
+Feature: Type matchers
+
+  rspec-expectations includes two matchers to specify types of objects:
+
+    * `expect(obj).to be_kind_of(type)`: calls `obj.kind_of?(type)`, which returns true if
+        type is in obj's class hierarchy or is a module and is included in a class in obj's
+        class hierarchy.
+    * `expect(obj).to be_instance_of(type)`: calls `obj.instance_of?(type)`, which returns
+        true if and only if type if obj's class.
+
+  Both of these matchers have aliases:
+
+    ```ruby
+    expect(obj).to be_a_kind_of(type)      # same as expect(obj).to be_kind_of(type)
+    expect(obj).to be_a(type)              # same as expect(obj).to be_kind_of(type)
+    expect(obj).to be_an(type)             # same as expect(obj).to be_kind_of(type)
+    expect(obj).to be_an_instance_of(type) # same as expect(obj).to be_instance_of(type)
+    ```
+
+  Scenario: be_(a_)kind_of matcher
+    Given a file named "be_kind_of_matcher_spec.rb" with:
+      """ruby
+      module MyModule; end
+
+      class Fixnum
+        include MyModule
+      end
+
+      RSpec.describe 17 do
+        # the actual class
+        it { is_expected.to be_kind_of(Fixnum) }
+        it { is_expected.to be_a_kind_of(Fixnum) }
+        it { is_expected.to be_a(Fixnum) }
+
+        # the superclass
+        it { is_expected.to be_kind_of(Integer) }
+        it { is_expected.to be_a_kind_of(Integer) }
+        it { is_expected.to be_an(Integer) }
+
+        # an included module
+        it { is_expected.to be_kind_of(MyModule) }
+        it { is_expected.to be_a_kind_of(MyModule) }
+        it { is_expected.to be_a(MyModule) }
+
+        # negative passing case
+        it { is_expected.not_to be_kind_of(String) }
+        it { is_expected.not_to be_a_kind_of(String) }
+        it { is_expected.not_to be_a(String) }
+
+        # deliberate failures
+        it { is_expected.not_to be_kind_of(Fixnum) }
+        it { is_expected.not_to be_a_kind_of(Fixnum) }
+        it { is_expected.not_to be_a(Fixnum) }
+        it { is_expected.not_to be_kind_of(Integer) }
+        it { is_expected.not_to be_a_kind_of(Integer) }
+        it { is_expected.not_to be_an(Integer) }
+        it { is_expected.not_to be_kind_of(MyModule) }
+        it { is_expected.not_to be_a_kind_of(MyModule) }
+        it { is_expected.not_to be_a(MyModule) }
+        it { is_expected.to be_kind_of(String) }
+        it { is_expected.to be_a_kind_of(String) }
+        it { is_expected.to be_a(String) }
+      end
+      """
+    When I run `rspec be_kind_of_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 24 examples, 12 failures                 |
+      | expected 17 not to be a kind of Fixnum   |
+      | expected 17 not to be a kind of Integer  |
+      | expected 17 not to be a kind of MyModule |
+      | expected 17 to be a kind of String       |
+
+  Scenario: be_(an_)instance_of matcher
+    Given a file named "be_instance_of_matcher_spec.rb" with:
+      """ruby
+      module MyModule; end
+
+      class Fixnum
+        include MyModule
+      end
+
+      RSpec.describe 17 do
+        # the actual class
+        it { is_expected.to be_instance_of(Fixnum) }
+        it { is_expected.to be_an_instance_of(Fixnum) }
+
+        # the superclass
+        it { is_expected.not_to be_instance_of(Integer) }
+        it { is_expected.not_to be_an_instance_of(Integer) }
+
+        # an included module
+        it { is_expected.not_to be_instance_of(MyModule) }
+        it { is_expected.not_to be_an_instance_of(MyModule) }
+
+        # another class with no relation to the subject's hierarchy
+        it { is_expected.not_to be_instance_of(String) }
+        it { is_expected.not_to be_an_instance_of(String) }
+
+        # deliberate failures
+        it { is_expected.not_to be_instance_of(Fixnum) }
+        it { is_expected.not_to be_an_instance_of(Fixnum) }
+        it { is_expected.to be_instance_of(Integer) }
+        it { is_expected.to be_an_instance_of(Integer) }
+        it { is_expected.to be_instance_of(MyModule) }
+        it { is_expected.to be_an_instance_of(MyModule) }
+        it { is_expected.to be_instance_of(String) }
+        it { is_expected.to be_an_instance_of(String) }
+      end
+      """
+    When I run `rspec be_instance_of_matcher_spec.rb`
+    Then the output should contain all of these:
+      | 16 examples, 8 failures                     |
+      | expected 17 not to be an instance of Fixnum |
+      | expected 17 to be an instance of Integer    |
+      | expected 17 to be an instance of MyModule   |
+      | expected 17 to be an instance of String     |
diff --git a/rspec-expectations/features/built_in_matchers/yield.feature b/rspec-expectations/features/built_in_matchers/yield.feature
new file mode 100644
index 0000000..1abb8fb
--- /dev/null
+++ b/rspec-expectations/features/built_in_matchers/yield.feature
@@ -0,0 +1,156 @@
+Feature: `yield` matchers
+
+  There are four related matchers that allow you to specify whether or not a method yields,
+  how many times it yields, whether or not it yields with arguments, and what those
+  arguments are.
+
+    * `yield_control` matches if the method-under-test yields, regardless of whether or not
+      arguments are yielded.
+    * `yield_with_args` matches if the method-under-test yields with arguments. If arguments
+      are provided to this matcher, it will only pass if the actual yielded arguments match the expected ones using `===` or `==`.
+    * `yield_with_no_args` matches if the method-under-test yields with no arguments.
+    * `yield_successive_args` is designed for iterators, and will match if the method-under-test
+       yields the same number of times as arguments passed to this matcher, and all actual yielded arguments match the expected ones using `===` or `==`.
+
+  Note: your expect block _must_ accept an argument that is then passed on to the
+  method-under-test as a block. This acts as a "probe" that allows the matcher to detect
+  whether or not your method yields, and, if so, how many times and what the yielded
+  arguments are.
+
+  Background:
+    Given a file named "my_class.rb" with:
+      """ruby
+      class MyClass
+        def self.yield_once_with(*args)
+          yield *args
+        end
+
+        def self.yield_twice_with(*args)
+          2.times { yield *args }
+        end
+
+        def self.raw_yield
+          yield
+        end
+
+        def self.dont_yield
+        end
+      end
+      """
+
+  Scenario: yield_control matcher
+    Given a file named "yield_control_spec.rb" with:
+      """ruby
+      require './my_class'
+
+      RSpec.describe "yield_control matcher" do
+        specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control }
+        specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_control }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.twice }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.exactly(2).times }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_least(1) }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_most(3).times }
+
+        # deliberate failures
+        specify { expect { |b| MyClass.yield_once_with(1, &b) }.not_to yield_control }
+        specify { expect { |b| MyClass.dont_yield(&b) }.to yield_control }
+        specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control.at_least(2).times }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.twice }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.at_least(2).times }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.at_least(1) }
+        specify { expect { |b| MyClass.yield_twice_with(1, &b) }.not_to yield_control.at_most(3).times }
+      end
+      """
+    When I run `rspec yield_control_spec.rb`
+    Then the output should contain all of these:
+      | 13 examples, 7 failures                                   |
+      | expected given block to yield control                     |
+      | expected given block not to yield control                 |
+      | expected given block not to yield control at least twice  |
+      | expected given block not to yield control at most 3 times |
+
+  Scenario: yield_with_args matcher
+    Given a file named "yield_with_args_spec.rb" with:
+      """ruby
+      require './my_class'
+
+      RSpec.describe "yield_with_args matcher" do
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args }
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args("foo") }
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args(String) }
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args(/oo/) }
+
+        specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args("foo", "bar") }
+        specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(String, String) }
+        specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(/fo/, /ar/) }
+
+        specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.not_to yield_with_args(17, "baz") }
+
+        # deliberate failures
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args }
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args("foo") }
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args(String) }
+        specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args(/oo/) }
+        specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.not_to yield_with_args("foo", "bar") }
+        specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(17, "baz") }
+      end
+      """
+    When I run `rspec yield_with_args_spec.rb`
+    Then the output should contain all of these:
+      | 14 examples, 6 failures                                                               |
+      | expected given block not to yield with arguments, but did                             |
+      | expected given block not to yield with arguments, but yielded with expected arguments |
+      | expected given block to yield with arguments, but yielded with unexpected arguments   |
+
+  Scenario: yield_with_no_args matcher
+    Given a file named "yield_with_no_args_spec.rb" with:
+      """ruby
+      require './my_class'
+
+      RSpec.describe "yield_with_no_args matcher" do
+        specify { expect { |b| MyClass.raw_yield(&b) }.to yield_with_no_args }
+        specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_with_no_args }
+        specify { expect { |b| MyClass.yield_once_with("a", &b) }.not_to yield_with_no_args }
+
+        # deliberate failures
+        specify { expect { |b| MyClass.raw_yield(&b) }.not_to yield_with_no_args }
+        specify { expect { |b| MyClass.dont_yield(&b) }.to yield_with_no_args }
+        specify { expect { |b| MyClass.yield_once_with("a", &b) }.to yield_with_no_args }
+      end
+      """
+    When I run `rspec yield_with_no_args_spec.rb`
+    Then the output should contain all of these:
+      | 6 examples, 3 failures                                                             |
+      | expected given block not to yield with no arguments, but did                       |
+      | expected given block to yield with no arguments, but did not yield                 |
+      | expected given block to yield with no arguments, but yielded with arguments: ["a"] |
+
+  Scenario: yield_successive_args matcher
+    Given a file named "yield_successive_args_spec.rb" with:
+      """ruby
+      def array
+        [1, 2, 3]
+      end
+
+      def array_of_tuples
+        [[:a, :b], [:c, :d]]
+      end
+
+      RSpec.describe "yield_successive_args matcher" do
+        specify { expect { |b| array.each(&b) }.to yield_successive_args(1, 2, 3) }
+        specify { expect { |b| array_of_tuples.each(&b) }.to yield_successive_args([:a, :b], [:c, :d]) }
+        specify { expect { |b| array.each(&b) }.to yield_successive_args(Fixnum, Fixnum, Fixnum) }
+        specify { expect { |b| array.each(&b) }.not_to yield_successive_args(1, 2) }
+
+        # deliberate failures
+        specify { expect { |b| array.each(&b) }.not_to yield_successive_args(1, 2, 3) }
+        specify { expect { |b| array_of_tuples.each(&b) }.not_to yield_successive_args([:a, :b], [:c, :d]) }
+        specify { expect { |b| array.each(&b) }.not_to yield_successive_args(Fixnum, Fixnum, Fixnum) }
+        specify { expect { |b| array.each(&b) }.to yield_successive_args(1, 2) }
+      end
+      """
+    When I run `rspec yield_successive_args_spec.rb`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures                                                                             |
+      | expected given block not to yield successively with arguments, but yielded with expected arguments |
+      | expected given block to yield successively with arguments, but yielded with unexpected arguments   |
diff --git a/rspec-expectations/features/composing_matchers.feature b/rspec-expectations/features/composing_matchers.feature
new file mode 100644
index 0000000..7fbd90c
--- /dev/null
+++ b/rspec-expectations/features/composing_matchers.feature
@@ -0,0 +1,246 @@
+Feature: Composing Matchers
+
+  RSpec's matchers are designed to be composable so that you can combine them to express
+  the exact details of what you expect but nothing more. This can help you avoid writing
+  over-specified brittle specs, by using a matcher in place of an exact value to specify only
+  the essential aspects of what you expect.
+
+  The following matchers accept matchers as arguments:
+
+    * `change { }.by(matcher)`
+    * `change { }.from(matcher).to(matcher)`
+    * `contain_exactly(matcher, matcher, matcher)`
+    * `end_with(matcher, matcher)`
+    * `include(matcher, matcher)`
+    * `include(:key => matcher, :other => matcher)`
+    * `match(arbitrary_nested_structure_with_matchers)`
+    * `output(matcher).to_stdout`
+    * `output(matcher).to_stderr`
+    * `raise_error(ErrorClass, matcher)`
+    * `start_with(matcher, matcher)`
+    * `throw_symbol(:sym, matcher)`
+    * `yield_with_args(matcher, matcher)`
+    * `yield_successive_args(matcher, matcher)`
+
+  Note that many built-in matchers do not accept matcher arguments because they have precise
+  semantics that do not allow for a matcher argument. For example, `equal(some_object)` is
+  designed to pass only if the actual and expected arguments are references to the same
+  object. It would not make sense to support a matcher argument here.
+
+  All of RSpec's built-in matchers have one or more aliases that allow you to use a noun-phrase
+  rather than verb form since they read better as composed arguments. They also provide
+  customized failure output so that the failure message reads better as well.
+
+  A full list of these aliases is out of scope here, but here are some of the aliases used below:
+
+    * `be < 2` => `a_value < 2`
+    * `be > 2` => `a_value > 2`
+    * `be_an_instance_of` => `an_instance_of`
+    * `be_within` => `a_value_within`
+    * `contain_exactly` => `a_collection_containing_exactly`
+    * `end_with` => `a_string_ending_with`, `ending_with`
+    * `match` => `a_string_matching`
+    * `start_with` => `a_string_starting_with`
+
+  For a full list, see the API docs for the `RSpec::Matchers` module.
+
+  Scenario: Composing matchers with `change`
+    Given a file named "change_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `change`" do
+        specify "you can pass a matcher to `by`" do
+          k = 0
+          expect { k += 1.05 }.to change { k }.
+            by( a_value_within(0.1).of(1.0) )
+        end
+
+        specify "you can pass matchers to `from` and `to" do
+          s = "food"
+          expect { s = "barn" }.to change { s }.
+            from( a_string_matching(/foo/) ).
+            to( a_string_matching(/bar/) )
+        end
+      end
+      """
+    When I run `rspec change_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `contain_exactly`
+    Given a file named "contain_exactly_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `contain_exactly`" do
+        specify "you can pass matchers in place of exact values" do
+          expect(["barn", 2.45]).to contain_exactly(
+            a_value_within(0.1).of(2.5),
+            a_string_starting_with("bar")
+          )
+        end
+      end
+      """
+    When I run `rspec contain_exactly_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `end_with`
+    Given a file named "end_with_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `end_with`" do
+        specify "you can pass matchers in place of exact values" do
+          expect(["barn", "food", 2.45]).to end_with(
+            a_string_matching("foo"),
+            a_value > 2
+          )
+        end
+      end
+      """
+    When I run `rspec end_with_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `include`
+    Given a file named "include_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `contain_exactly`" do
+        specify "you can use matchers in place of array values" do
+          expect(["barn", 2.45]).to include( a_string_starting_with("bar") )
+        end
+
+        specify "you can use matchers in place of hash values" do
+          expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/))
+        end
+
+        specify "you can use matchers in place of hash keys" do
+          expect("food" => "is good").to include( a_string_matching(/foo/) )
+        end
+      end
+      """
+    When I run `rspec include_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `match`:
+    Given a file named "match_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `match`" do
+        specify "you can match nested data structures against matchers" do
+          hash = {
+            :a => {
+              :b => ["foo", 5],
+              :c => { :d => 2.05 }
+            }
+          }
+
+          expect(hash).to match(
+            :a => {
+              :b => a_collection_containing_exactly(
+                a_string_starting_with("f"),
+                an_instance_of(Fixnum)
+              ),
+              :c => { :d => (a_value < 3) }
+            }
+          )
+        end
+      end
+      """
+    When I run `rspec match_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `output`
+    Given a file named "output_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `output`" do
+        specify "you can pass a matcher in place of the output (to_stdout)" do
+          expect {
+            print 'foo'
+          }.to output(a_string_starting_with('f')).to_stdout
+        end
+        specify "you can pass a matcher in place of the output (to_stderr)" do
+          expect {
+            warn 'foo'
+          }.to output(a_string_starting_with('f')).to_stderr
+        end
+      end
+      """
+    When I run `rspec output_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `raise_error`
+    Given a file named "raise_error_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `raise_error`" do
+        specify "you can pass a matcher in place of the message" do
+          expect {
+            raise RuntimeError, "this goes boom"
+          }.to raise_error(RuntimeError, a_string_ending_with("boom"))
+        end
+      end
+      """
+    When I run `rspec raise_error_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `start_with`
+    Given a file named "start_with_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `start_with`" do
+        specify "you can pass matchers in place of exact values" do
+          expect(["barn", "food", 2.45]).to start_with(
+            a_string_matching("bar"),
+            a_string_matching("foo")
+          )
+        end
+      end
+      """
+    When I run `rspec start_with_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `throw_symbol`
+    Given a file named "throw_symbol_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `throw_symbol`" do
+        specify "you can pass a matcher in place of a throw arg" do
+          expect {
+            throw :pi, Math::PI
+          }.to throw_symbol(:pi, a_value_within(0.01).of(3.14))
+        end
+      end
+      """
+    When I run `rspec throw_symbol_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `yield_with_args`
+    Given a file named "yield_with_args_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `yield_with_args`" do
+        specify "you can pass matchers in place of the args" do
+          expect { |probe|
+            "food".tap(&probe)
+          }.to yield_with_args(a_string_matching(/foo/))
+        end
+      end
+      """
+    When I run `rspec yield_with_args_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers with `yield_successive_args`
+    Given a file named "yield_successive_args_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing matchers to `yield_successive_args`" do
+        specify "you can pass matchers in place of the args" do
+          expect { |probe|
+            [1, 2, 3].each(&probe)
+          }.to yield_successive_args(a_value < 2, 2, a_value > 2)
+        end
+      end
+      """
+    When I run `rspec yield_successive_args_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Composing matchers using a compound `and` expression
+    Given a file named "include_spec.rb" with:
+      """ruby
+      RSpec.describe "Passing a compound matcher expression to `include`" do
+        example do
+          expect(["food", "drink"]).to include( a_string_starting_with("f").and ending_with("d"))
+        end
+      end
+      """
+    When I run `rspec include_spec.rb`
+    Then the examples should all pass
+
diff --git a/rspec-expectations/features/compound_expectations.feature b/rspec-expectations/features/compound_expectations.feature
new file mode 100644
index 0000000..336f78f
--- /dev/null
+++ b/rspec-expectations/features/compound_expectations.feature
@@ -0,0 +1,52 @@
+Feature: Compound Expectations
+
+  Matchers can be composed using `and` or `or` to make compound expectations.
+
+  Scenario: Use `and` to chain expectations
+    Given a file named "compound_and_matcher_spec.rb" with:
+      """ruby
+      RSpec.describe "A compound `and` matcher" do
+        let(:string) { "foo bar bazz" }
+
+        it "passes when both are true" do
+          expect(string).to start_with("foo").and end_with("bazz")
+        end
+
+        it "passes when using boolean AND `&` alias" do
+          expect(string).to start_with("foo") & end_with("bazz")
+        end
+
+        it "fails when the first matcher fails" do
+          expect(string).to start_with("bar").and end_with("bazz")
+        end
+
+        it "fails when the second matcher fails" do
+          expect(string).to start_with("foo").and end_with("bar")
+        end
+      end
+      """
+    When I run `rspec compound_and_matcher_spec.rb`
+    Then the output should contain "4 examples, 2 failures"
+
+  Scenario: Use `or` to chain expectations
+    Given a file named "stoplight_spec.rb" with:
+      """ruby
+      class StopLight
+        def color
+          %w[ green yellow red ].shuffle.first
+        end
+      end
+
+      RSpec.describe StopLight, "#color" do
+        let(:light) { StopLight.new }
+        it "is green, yellow or red" do
+          expect(light.color).to eq("green").or eq("yellow").or eq("red")
+        end
+
+        it "passes when using boolean OR `|` alias" do
+          expect(light.color).to eq("green") | eq("yellow") | eq("red")
+        end
+      end
+      """
+    When I run `rspec stoplight_spec.rb`
+    Then the example should pass
diff --git a/rspec-expectations/features/custom_matchers/access_running_example.feature b/rspec-expectations/features/custom_matchers/access_running_example.feature
new file mode 100644
index 0000000..8733533
--- /dev/null
+++ b/rspec-expectations/features/custom_matchers/access_running_example.feature
@@ -0,0 +1,48 @@
+Feature: access running example
+
+  In the context of a custom matcher, you can call helper methods that are available from the
+  current example's example group. This is used, for example, by rspec-rails in order to wrap
+  rails' built-in assertions (which depend on helper methods available in the test context).
+
+  Scenario: call method defined on example from matcher
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :bar do
+        match do |_|
+          foo == "foo"
+        end
+      end
+
+      RSpec.describe "something" do
+        def foo
+          "foo"
+        end
+
+        it "does something" do
+          expect("foo").to bar
+        end
+      end
+      """
+    When I run `rspec ./example_spec.rb`
+    Then the output should contain "1 example, 0 failures"
+
+  Scenario: call method _not_ defined on example from matcher
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :bar do
+        match do |_|
+          foo == "foo"
+        end
+      end
+
+      RSpec.describe "something" do
+        it "does something" do
+          expect("foo").to bar
+        end
+      end
+      """
+    When I run `rspec ./example_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+    And the output should match /undefined.*method/
+    And the output should contain "RSpec::Matchers::DSL::Matcher"
+    And the output should not contain "ExampleGroup"
diff --git a/rspec-expectations/features/custom_matchers/define_block_matcher.feature b/rspec-expectations/features/custom_matchers/define_block_matcher.feature
new file mode 100644
index 0000000..06b8a95
--- /dev/null
+++ b/rspec-expectations/features/custom_matchers/define_block_matcher.feature
@@ -0,0 +1,44 @@
+Feature: define a matcher supporting block expectations
+
+  When you wish to support block expectations (e.g. `expect { ... }.to matcher`) with
+  your custom matchers you must specify this. You can do this manually (or determinately
+  based on some logic) by defining a `supports_block_expectation?` method or by using
+  the DSL's `supports_block_expectations` shortcut method.
+
+  Scenario: define a block matcher manually
+    Given a file named "block_matcher_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :support_blocks do
+        match do |actual|
+          actual.is_a? Proc
+        end
+
+        def supports_block_expectations?
+          true # or some logic
+        end
+      end
+
+      RSpec.describe "a custom block matcher" do
+        specify { expect { }.to support_blocks }
+      end
+      """
+    When I run `rspec ./block_matcher_spec.rb`
+    Then the example should pass
+
+  Scenario: define a block matcher using shortcut
+    Given a file named "block_matcher_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :support_blocks do
+        match do |actual|
+          actual.is_a? Proc
+        end
+
+        supports_block_expectations
+      end
+
+      RSpec.describe "a custom block matcher" do
+        specify { expect { }.to support_blocks }
+      end
+      """
+    When I run `rspec ./block_matcher_spec.rb`
+    Then the example should pass
diff --git a/rspec-expectations/features/custom_matchers/define_diffable_matcher.feature b/rspec-expectations/features/custom_matchers/define_diffable_matcher.feature
new file mode 100644
index 0000000..4b1d3a0
--- /dev/null
+++ b/rspec-expectations/features/custom_matchers/define_diffable_matcher.feature
@@ -0,0 +1,29 @@
+Feature: define diffable matcher
+
+  When a matcher is defined as diffable, the output will include a diff of the submitted
+  objects when the objects are more than simple primitives.
+
+  Scenario: define a diffable matcher
+    Given a file named "diffable_matcher_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :be_just_like do |expected|
+        match do |actual|
+          actual == expected
+        end
+
+        diffable
+      end
+
+      RSpec.describe "two\nlines" do
+        it { is_expected.to be_just_like("three\nlines") }
+      end
+      """
+    When I run `rspec ./diffable_matcher_spec.rb`
+    Then it should fail with:
+      """
+             Diff:
+             @@ -1,3 +1,3 @@
+             -three
+             +two
+              lines
+      """
diff --git a/rspec-expectations/features/custom_matchers/define_matcher.feature b/rspec-expectations/features/custom_matchers/define_matcher.feature
new file mode 100644
index 0000000..824ede0
--- /dev/null
+++ b/rspec-expectations/features/custom_matchers/define_matcher.feature
@@ -0,0 +1,337 @@
+Feature: define matcher
+
+  rspec-expectations provides a DSL for defining custom matchers. These are often useful for
+  expressing expectations in the domain of your application.
+
+  Scenario: define a matcher with default messages
+    Given a file named "matcher_with_default_message_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        match do |actual|
+          actual % expected == 0
+        end
+      end
+
+      RSpec.describe 9 do
+        it { is_expected.to be_a_multiple_of(3) }
+      end
+
+      RSpec.describe 9 do
+        it { is_expected.not_to be_a_multiple_of(4) }
+      end
+
+      # fail intentionally to generate expected output
+      RSpec.describe 9 do
+        it { is_expected.to be_a_multiple_of(4) }
+      end
+
+      # fail intentionally to generate expected output
+      RSpec.describe 9 do
+        it { is_expected.not_to be_a_multiple_of(3) }
+      end
+      """
+    When I run `rspec ./matcher_with_default_message_spec.rb --format documentation`
+    Then the exit status should not be 0
+
+    And the output should contain "should be a multiple of 3"
+    And the output should contain "should not be a multiple of 4"
+    And the output should contain "Failure/Error: it { is_expected.to be_a_multiple_of(4) }"
+    And the output should contain "Failure/Error: it { is_expected.not_to be_a_multiple_of(3) }"
+
+    And the output should contain "4 examples, 2 failures"
+    And the output should contain "expected 9 to be a multiple of 4"
+    And the output should contain "expected 9 not to be a multiple of 3"
+
+  Scenario: overriding the failure_message
+    Given a file named "matcher_with_failure_message_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        match do |actual|
+          actual % expected == 0
+        end
+        failure_message do |actual|
+          "expected that #{actual} would be a multiple of #{expected}"
+        end
+      end
+
+      # fail intentionally to generate expected output
+      RSpec.describe 9 do
+        it { is_expected.to be_a_multiple_of(4) }
+      end
+      """
+    When I run `rspec ./matcher_with_failure_message_spec.rb`
+    Then the exit status should not be 0
+    And the stdout should contain "1 example, 1 failure"
+    And the stdout should contain "expected that 9 would be a multiple of 4"
+
+  Scenario: overriding the failure_message_when_negated
+    Given a file named "matcher_with_failure_for_message_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        match do |actual|
+          actual % expected == 0
+        end
+        failure_message_when_negated do |actual|
+          "expected that #{actual} would not be a multiple of #{expected}"
+        end
+      end
+
+      # fail intentionally to generate expected output
+      RSpec.describe 9 do
+        it { is_expected.not_to be_a_multiple_of(3) }
+      end
+      """
+    When I run `rspec ./matcher_with_failure_for_message_spec.rb`
+    Then the exit status should not be 0
+    And the stdout should contain "1 example, 1 failure"
+    And the stdout should contain "expected that 9 would not be a multiple of 3"
+
+  Scenario: overriding the description
+    Given a file named "matcher_overriding_description_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        match do |actual|
+          actual % expected == 0
+        end
+        description do
+          "be multiple of #{expected}"
+        end
+      end
+
+      RSpec.describe 9 do
+        it { is_expected.to be_a_multiple_of(3) }
+      end
+
+      RSpec.describe 9 do
+        it { is_expected.not_to be_a_multiple_of(4) }
+      end
+      """
+    When I run `rspec ./matcher_overriding_description_spec.rb --format documentation`
+    Then the exit status should be 0
+    And the stdout should contain "2 examples, 0 failures"
+    And the stdout should contain "should be multiple of 3"
+    And the stdout should contain "should not be multiple of 4"
+
+  Scenario: with no args
+    Given a file named "matcher_with_no_args_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :have_7_fingers do
+        match do |thing|
+          thing.fingers.length == 7
+        end
+      end
+
+      class Thing
+        def fingers; (1..7).collect {"finger"}; end
+      end
+
+      RSpec.describe Thing do
+        it { is_expected.to have_7_fingers }
+      end
+      """
+    When I run `rspec ./matcher_with_no_args_spec.rb --format documentation`
+    Then the exit status should be 0
+    And the stdout should contain "1 example, 0 failures"
+    And the stdout should contain "should have 7 fingers"
+
+  Scenario: with multiple args
+    Given a file named "matcher_with_multiple_args_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :be_the_sum_of do |a,b,c,d|
+        match do |sum|
+          a + b + c + d == sum
+        end
+      end
+
+      RSpec.describe 10 do
+        it { is_expected.to be_the_sum_of(1,2,3,4) }
+      end
+      """
+    When I run `rspec ./matcher_with_multiple_args_spec.rb --format documentation`
+    Then the exit status should be 0
+    And the stdout should contain "1 example, 0 failures"
+    And the stdout should contain "should be the sum of 1, 2, 3, and 4"
+
+  Scenario: with helper methods
+    Given a file named "matcher_with_internal_helper_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec::Matchers.define :have_same_elements_as do |sample|
+        match do |actual|
+          similar?(sample, actual)
+        end
+
+        def similar?(a, b)
+          a.sort == b.sort
+        end
+      end
+
+      RSpec.describe "these two arrays" do
+        specify "should be similar" do
+          expect([1,2,3]).to have_same_elements_as([2,3,1])
+        end
+      end
+      """
+    When I run `rspec ./matcher_with_internal_helper_spec.rb`
+    Then the exit status should be 0
+    And the stdout should contain "1 example, 0 failures"
+
+  Scenario: scoped in a module
+    Given a file named "scoped_matcher_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      module MyHelpers
+        extend RSpec::Matchers::DSL
+
+        matcher :be_just_like do |expected|
+          match {|actual| actual == expected}
+        end
+      end
+
+      RSpec.describe "group with MyHelpers" do
+        include MyHelpers
+        it "has access to the defined matcher" do
+          expect(5).to be_just_like(5)
+        end
+      end
+
+      RSpec.describe "group without MyHelpers" do
+        it "does not have access to the defined matcher" do
+          expect do
+            expect(5).to be_just_like(5)
+          end.to raise_exception
+        end
+      end
+      """
+
+    When I run `rspec ./scoped_matcher_spec.rb`
+    Then the stdout should contain "2 examples, 0 failures"
+
+  Scenario: scoped in an example group
+    Given a file named "scoped_matcher_spec.rb" with:
+      """ruby
+      require 'rspec/expectations'
+
+      RSpec.describe "group with matcher" do
+        matcher :be_just_like do |expected|
+          match {|actual| actual == expected}
+        end
+
+        it "has access to the defined matcher" do
+          expect(5).to be_just_like(5)
+        end
+
+        describe "nested group" do
+          it "has access to the defined matcher" do
+            expect(5).to be_just_like(5)
+          end
+        end
+      end
+
+      RSpec.describe "group without matcher" do
+        it "does not have access to the defined matcher" do
+          expect do
+            expect(5).to be_just_like(5)
+          end.to raise_exception
+        end
+      end
+      """
+
+    When I run `rspec scoped_matcher_spec.rb`
+    Then the output should contain "3 examples, 0 failures"
+
+  Scenario: matcher with separate logic for should and should_not
+    Given a file named "matcher_with_separate_should_not_logic_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :contain do |*expected|
+        match do |actual|
+          expected.all? { |e| actual.include?(e) }
+        end
+
+        match_when_negated do |actual|
+          expected.none? { |e| actual.include?(e) }
+        end
+      end
+
+      RSpec.describe [1, 2, 3] do
+        it { is_expected.to contain(1, 2) }
+        it { is_expected.not_to contain(4, 5, 6) }
+
+        # deliberate failures
+        it { is_expected.to contain(1, 4) }
+        it { is_expected.not_to contain(1, 4) }
+      end
+      """
+    When I run `rspec matcher_with_separate_should_not_logic_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures                    |
+      | expected [1, 2, 3] to contain 1 and 4     |
+      | expected [1, 2, 3] not to contain 1 and 4 |
+
+  Scenario: use define_method to create a helper method with access to matcher params
+    Given a file named "define_method_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        define_method :is_multiple? do |actual|
+          actual % expected == 0
+        end
+        match { |actual| is_multiple?(actual) }
+      end
+
+      RSpec.describe 9 do
+        it { is_expected.to be_a_multiple_of(3) }
+        it { is_expected.not_to be_a_multiple_of(4) }
+
+        # deliberate failures
+        it { is_expected.to be_a_multiple_of(2) }
+        it { is_expected.not_to be_a_multiple_of(3) }
+      end
+      """
+    When I run `rspec define_method_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures               |
+      | expected 9 to be a multiple of 2     |
+      | expected 9 not to be a multiple of 3 |
+
+  Scenario: include a module with helper methods in the matcher
+    Given a file named "include_module_spec.rb" with:
+      """ruby
+      module MatcherHelpers
+        def is_multiple?(actual, expected)
+          actual % expected == 0
+        end
+      end
+
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        include MatcherHelpers
+        match { |actual| is_multiple?(actual, expected) }
+      end
+
+      RSpec.describe 9 do
+        it { is_expected.to be_a_multiple_of(3) }
+        it { is_expected.not_to be_a_multiple_of(4) }
+
+        # deliberate failures
+        it { is_expected.to be_a_multiple_of(2) }
+        it { is_expected.not_to be_a_multiple_of(3) }
+      end
+      """
+    When I run `rspec include_module_spec.rb`
+    Then the output should contain all of these:
+      | 4 examples, 2 failures               |
+      | expected 9 to be a multiple of 2     |
+      | expected 9 not to be a multiple of 3 |
diff --git a/rspec-expectations/features/custom_matchers/define_matcher_outside_rspec.feature b/rspec-expectations/features/custom_matchers/define_matcher_outside_rspec.feature
new file mode 100644
index 0000000..2c889b6
--- /dev/null
+++ b/rspec-expectations/features/custom_matchers/define_matcher_outside_rspec.feature
@@ -0,0 +1,32 @@
+Feature: define matcher outside rspec
+
+  You can define custom matchers when using rspec-expectations outside of rspec-core.
+
+  Scenario: define a matcher with default messages
+    Given a file named "test_multiples.rb" with:
+      """ruby
+      require "minitest/autorun"
+      require "rspec/expectations/minitest_integration"
+
+      RSpec::Matchers.define :be_a_multiple_of do |expected|
+        match do |actual|
+          actual % expected == 0
+        end
+      end
+
+      class TestMultiples < Minitest::Test
+
+        def test_9_should_be_a_multiple_of_3
+          expect(9).to be_a_multiple_of(3)
+        end
+
+        def test_9_should_be_a_multiple_of_4
+          expect(9).to be_a_multiple_of(4)
+        end
+
+      end
+      """
+    When I run `ruby test_multiples.rb`
+    Then the exit status should not be 0
+    And the output should contain "expected 9 to be a multiple of 4"
+    And the output should contain "2 runs, 2 assertions, 1 failures, 0 errors"
diff --git a/rspec-expectations/features/custom_matchers/define_matcher_with_fluent_interface.feature b/rspec-expectations/features/custom_matchers/define_matcher_with_fluent_interface.feature
new file mode 100644
index 0000000..5d1d29b
--- /dev/null
+++ b/rspec-expectations/features/custom_matchers/define_matcher_with_fluent_interface.feature
@@ -0,0 +1,70 @@
+Feature: define matcher with fluent interface
+
+  Use the `chain` method to define matchers with a fluent interface.
+
+  Scenario: chained method with argument
+    Given a file named "between_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :be_bigger_than do |first|
+        match do |actual|
+          (actual > first) && (actual < @second)
+        end
+
+        chain :and_smaller_than do |second|
+          @second = second
+        end
+      end
+
+      RSpec.describe 5 do
+        it { is_expected.to be_bigger_than(4).and_smaller_than(6) }
+      end
+      """
+    When I run `rspec between_spec.rb --format documentation`
+    Then the output should contain "1 example, 0 failures"
+    And  the output should contain "should be bigger than 4"
+
+  Scenario: chained setter
+    Given a file named "between_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :be_bigger_than do |first|
+        match do |actual|
+          (actual > first) && (actual < second)
+        end
+
+        chain :and_smaller_than, :second
+      end
+
+      RSpec.describe 5 do
+        it { is_expected.to be_bigger_than(4).and_smaller_than(6) }
+      end
+      """
+    When I run `rspec between_spec.rb --format documentation`
+    Then the output should contain "1 example, 0 failures"
+    And  the output should contain "should be bigger than 4"
+
+    Scenario: include_chain_clauses_in_custom_matcher_descriptions configured to true, and chained method with argument
+      Given a file named "between_spec.rb" with:
+        """ruby
+        RSpec.configure do |config|
+          config.expect_with :rspec do |c|
+            c.include_chain_clauses_in_custom_matcher_descriptions = true
+          end
+        end
+
+        RSpec::Matchers.define :be_bigger_than do |first|
+          match do |actual|
+            (actual > first) && (actual < @second)
+          end
+
+          chain :and_smaller_than do |second|
+            @second = second
+          end
+        end
+
+        RSpec.describe 5 do
+          it { is_expected.to be_bigger_than(4).and_smaller_than(6) }
+        end
+        """
+      When I run `rspec between_spec.rb --format documentation`
+      Then the output should contain "1 example, 0 failures"
+      And  the output should contain "should be bigger than 4 and smaller than 6"
diff --git a/rspec-expectations/features/customized_message.feature b/rspec-expectations/features/customized_message.feature
new file mode 100644
index 0000000..c96a3ea
--- /dev/null
+++ b/rspec-expectations/features/customized_message.feature
@@ -0,0 +1,39 @@
+Feature: customized message
+
+  RSpec tries to provide useful failure messages, but for cases in which you want more
+  specific information, you can define your own message right in the example.This works for
+  any matcher _other than the operator matchers_.
+
+  Scenario: customize failure message
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        context "when created with `new`" do
+          it "is empty" do
+            array = Array.new
+            array << 1 # trigger a failure to demonstrate the message
+            expect(array).to be_empty, "expected empty array, got #{array.inspect}"
+          end
+        end
+      end
+
+      """
+    When I run `rspec example_spec.rb --format documentation`
+    Then the output should contain "expected empty array, got [1]"
+
+  Scenario: customize failure message with a proc
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe Array do
+        context "when created with `new`" do
+          it "is empty" do
+            array = Array.new
+            array << 1 # trigger a failure to demonstrate the message
+            expect(array).to be_empty, lambda { "expected empty array, got #{array.inspect}" }
+          end
+        end
+      end
+
+      """
+    When I run `rspec example_spec.rb --format documentation`
+    Then the output should contain "expected empty array, got [1]"
diff --git a/rspec-expectations/features/define_negated_matcher.feature b/rspec-expectations/features/define_negated_matcher.feature
new file mode 100644
index 0000000..f13a09b
--- /dev/null
+++ b/rspec-expectations/features/define_negated_matcher.feature
@@ -0,0 +1,29 @@
+Feature: Define negated matcher
+
+  You can use `RSpec::Matchers.define_negated_matcher` to define a negated version of
+  an existing matcher. This is particularly useful in composed matcher expressions.
+
+  Scenario: Composed negated matcher expression
+    Given a file named "composed_negated_expression_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define_negated_matcher :an_array_excluding, :include
+
+      RSpec.describe "A negated matcher" do
+        let(:list) { 1.upto(10).to_a }
+
+        it "can be used in a composed matcher expression" do
+          expect { list.delete(5) }.to change { list }.to(an_array_excluding 5)
+        end
+
+        it "provides a good failure message based on the name" do
+          # deliberate failure
+          expect { list.delete(1) }.to change { list }.to(an_array_excluding 5)
+        end
+      end
+      """
+    When I run `rspec composed_negated_expression_spec.rb`
+    Then the output should contain all of these:
+      | 2 examples, 1 failure                                                                                  |
+      |  1) A negated matcher provides a good failure message based on the name                                |
+      |     Failure/Error: expect { list.delete(1) }.to change { list }.to(an_array_excluding 5)               |
+      |       expected result to have changed to an array excluding 5, but is now [2, 3, 4, 5, 6, 7, 8, 9, 10] |
diff --git a/rspec-expectations/features/diffing.feature b/rspec-expectations/features/diffing.feature
new file mode 100644
index 0000000..8f53211
--- /dev/null
+++ b/rspec-expectations/features/diffing.feature
@@ -0,0 +1,85 @@
+Feature: diffing
+
+  When appropriate, failure messages will automatically include a diff.
+
+  Scenario: diff for a multiline string
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "a multiline string" do
+        it "is like another string" do
+          expected = <<-EXPECTED
+      this is the
+        expected
+          string
+      EXPECTED
+          actual = <<-ACTUAL
+      this is the
+        actual
+          string
+      ACTUAL
+          expect(actual).to eq(expected)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain:
+      """
+             Diff:
+             @@ -1,4 +1,4 @@
+              this is the
+             -  expected
+             +  actual
+                  string
+      """
+
+  Scenario: diff for a multiline string and a regexp
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "a multiline string" do
+        it "is like another string" do
+          expected = /expected/m
+          actual = <<-ACTUAL
+      this is the
+        actual
+          string
+      ACTUAL
+          expect(actual).to match expected
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should contain:
+      """
+             Diff:
+             @@ -1,2 +1,4 @@
+             -/expected/m
+             +this is the
+             +  actual
+             +    string
+      """
+
+  Scenario: no diff for a single line strings
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "a single line string" do
+        it "is like another string" do
+          expected = "this string"
+          actual   = "that string"
+          expect(actual).to eq(expected)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should not contain "Diff:"
+
+  Scenario: no diff for numbers
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "a number" do
+        it "is like another number" do
+          expect(1).to eq(2)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the output should not contain "Diff:"
diff --git a/rspec-expectations/features/implicit_docstrings.feature b/rspec-expectations/features/implicit_docstrings.feature
new file mode 100644
index 0000000..f6481a7
--- /dev/null
+++ b/rspec-expectations/features/implicit_docstrings.feature
@@ -0,0 +1,51 @@
+Feature: implicit docstrings
+
+  When you use rspec-expectations with rspec-core, RSpec is able to auto-generate the
+  docstrings for examples for you based on the last expectation in the example. This can be
+  handy when the matcher expresses exactly what you would write in your example docstring,
+  but it can also be easily abused. We find that the freeform nature of the docstring provides
+  a lot of value when used well (e.g. to document the "why" of a particular behavior), and you
+  lose that kind of flexibility when you rely on the matcher to generate the docstring for you.
+
+  In general, we recommend only using this feature when the matcher aligns _exactly_ with the
+  docstring you would write. Even then, many users prefer the explicitness of the full
+  docstring, so use this feature with care (if at all).
+
+  Scenario: run passing examples
+    Given a file named "implicit_docstrings_spec.rb" with:
+    """ruby
+    RSpec.describe "Examples with no docstrings generate their own:" do
+      specify { expect(3).to be < 5 }
+      specify { expect([1,2,3]).to include(2) }
+      specify { expect([1,2,3]).to respond_to(:size) }
+    end
+    """
+
+    When I run `rspec ./implicit_docstrings_spec.rb -fdoc`
+
+    Then the output should contain "should be < 5"
+    And the output should contain "should include 2"
+    And the output should contain "should respond to #size"
+
+  Scenario: run failing examples
+    Given a file named "failing_implicit_docstrings_spec.rb" with:
+    """ruby
+    RSpec.describe "Failing examples with no descriptions" do
+      # description is auto-generated as "to equal(5)" based on the last #expect
+      specify do
+        expect(3).to equal(2)
+        expect(5).to equal(5)
+      end
+
+      specify { expect(3).to be > 5 }
+      specify { expect([1,2,3]).to include(4) }
+      specify { expect([1,2,3]).not_to respond_to(:size) }
+    end
+    """
+
+    When I run `rspec ./failing_implicit_docstrings_spec.rb -fdoc`
+
+    Then the output should contain "should equal 2"
+    And the output should contain "should be > 5"
+    And the output should contain "should include 4"
+    And the output should contain "should not respond to #size"
diff --git a/rspec-expectations/features/step_definitions/additional_cli_steps.rb b/rspec-expectations/features/step_definitions/additional_cli_steps.rb
new file mode 100644
index 0000000..b5ff82b
--- /dev/null
+++ b/rspec-expectations/features/step_definitions/additional_cli_steps.rb
@@ -0,0 +1,22 @@
+# Useful for when the output is slightly different on different versions of ruby
+Then /^the output should contain "([^"]*)" or "([^"]*)"$/ do |string1, string2|
+  unless [string1, string2].any? { |s| all_output.include?(s) }
+    fail %Q{Neither "#{string1}" or "#{string2}" were found in:\n#{all_output}}
+  end
+end
+
+Then /^the output should contain all of these:$/ do |table|
+  table.raw.flatten.each do |string|
+    assert_partial_output(string, all_output)
+  end
+end
+
+Then /^the example(?:s)? should(?: all)? pass$/ do
+  step %q{the output should contain "0 failures"}
+  step %q{the exit status should be 0}
+end
+
+Then /^the example should fail$/ do
+  step %q{the output should contain "1 failure"}
+  step %q{the exit status should not be 0}
+end
diff --git a/rspec-expectations/features/support/disallow_certain_apis.rb b/rspec-expectations/features/support/disallow_certain_apis.rb
new file mode 100644
index 0000000..ebcdd89
--- /dev/null
+++ b/rspec-expectations/features/support/disallow_certain_apis.rb
@@ -0,0 +1,34 @@
+# This file is designed to prevent the use of certain APIs that
+# we don't want used from our cukes, since they function as documentation.
+
+if defined?(Cucumber)
+  require 'shellwords'
+  Before('~@allow-disallowed-api') do
+    set_env('SPEC_OPTS', "-r#{Shellwords.escape(__FILE__)}")
+  end
+else
+  module DisallowOneLinerShould
+    def should(*)
+      raise "one-liner should is not allowed"
+    end
+
+    def should_not(*)
+      raise "one-liner should_not is not allowed"
+    end
+  end
+
+  RSpec.configure do |rspec|
+    rspec.expose_dsl_globally = false
+
+    rspec.mock_with :rspec do |mocks|
+      mocks.syntax = :expect
+    end
+
+    rspec.expect_with :rspec do |expectations|
+      expectations.syntax = :expect
+    end
+
+    rspec.include DisallowOneLinerShould
+  end
+end
+
diff --git a/rspec-expectations/features/support/env.rb b/rspec-expectations/features/support/env.rb
new file mode 100644
index 0000000..36b8026
--- /dev/null
+++ b/rspec-expectations/features/support/env.rb
@@ -0,0 +1,21 @@
+require 'aruba/cucumber'
+
+Before do
+  if RUBY_PLATFORM =~ /java/ || defined?(Rubinius)
+    @aruba_timeout_seconds = 60
+  else
+    @aruba_timeout_seconds = 10
+  end
+end
+
+Aruba.configure do |config|
+  config.before_cmd do |cmd|
+    set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
+  end
+end if RUBY_PLATFORM == 'java'
+
+Aruba.configure do |config|
+  config.before_cmd do |cmd|
+    set_env('RBXOPT', "-Xint=true #{ENV['RBXOPT']}") # disable JIT since these processes are so short lived
+  end
+end if defined?(Rubinius)
diff --git a/rspec-expectations/features/support/rubinius.rb b/rspec-expectations/features/support/rubinius.rb
new file mode 100644
index 0000000..3907962
--- /dev/null
+++ b/rspec-expectations/features/support/rubinius.rb
@@ -0,0 +1,6 @@
+# Required until https://github.com/rubinius/rubinius/issues/2430 is resolved
+ENV['RBXOPT'] = "#{ENV["RBXOPT"]} -Xcompiler.no_rbc"
+
+Around "@unsupported-on-rbx" do |scenario, block|
+  block.call unless defined?(Rubinius)
+end
diff --git a/rspec-expectations/features/syntax_configuration.feature b/rspec-expectations/features/syntax_configuration.feature
new file mode 100644
index 0000000..5eaeb5e
--- /dev/null
+++ b/rspec-expectations/features/syntax_configuration.feature
@@ -0,0 +1,92 @@
+ at allow-disallowed-api
+Feature: Syntax Configuration
+
+  The primary syntax provided by rspec-expectations is based on
+  the `expect` method, which explicitly wraps an object or block
+  of code in order to set an expectation on it.
+
+  There's also an older `should`-based syntax, which relies upon `should` being
+  monkey-patched onto every object in the system.However, this syntax can at times lead to
+  some surprising failures, since RSpec does not own every object in the system and cannot
+  guarantee that it will always work consistently.
+
+  We recommend you use the `expect` syntax unless you have a specific reason you prefer the
+  `should` syntax. We have no plans to ever completely remove the `should` syntax but starting
+  in RSpec 3, a deprecation warning will be issued if you do not explicitly enable it, with the
+  plan to disable it by default in RSpec 4 (and potentially move it into an external gem).
+
+  If you have an old `should`-based project that you would like to upgrade to the `expect`,
+  check out [transpec](http://yujinakayama.me/transpec/), which can perform the conversion automatically for you.
+
+  Background:
+    Given a file named "spec/syntaxes_spec.rb" with:
+      """ruby
+      require 'spec_helper'
+
+      RSpec.describe "using the should syntax" do
+        specify { 3.should eq(3) }
+        specify { 3.should_not eq(4) }
+        specify { lambda { raise "boom" }.should raise_error("boom") }
+        specify { lambda { }.should_not raise_error }
+      end
+
+      RSpec.describe "using the expect syntax" do
+        specify { expect(3).to eq(3) }
+        specify { expect(3).not_to eq(4) }
+        specify { expect { raise "boom" }.to raise_error("boom") }
+        specify { expect { }.not_to raise_error }
+      end
+      """
+
+  Scenario: Both syntaxes are available by default
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      """
+    When I run `rspec`
+    Then the examples should all pass
+    And the output should contain "Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated"
+
+  Scenario: Disable should syntax
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :rspec do |c|
+          c.syntax = :expect
+        end
+      end
+      """
+    When I run `rspec`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures    |
+      | undefined method `should' |
+
+  Scenario: Disable expect syntax
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :rspec do |c|
+          c.syntax = :should
+        end
+        config.mock_with :rspec do |c|
+          c.syntax = :should
+        end
+      end
+      """
+    When I run `rspec`
+    Then the output should contain all of these:
+      | 8 examples, 4 failures    |
+      | undefined method `expect' |
+
+  Scenario: Explicitly enable both syntaxes
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.expect_with :rspec do |c|
+          c.syntax = [:should, :expect]
+        end
+      end
+      """
+    When I run `rspec`
+    Then the examples should all pass
+     And the output should not contain "deprecated"
+
diff --git a/rspec-expectations/features/test_frameworks/minitest.feature b/rspec-expectations/features/test_frameworks/minitest.feature
new file mode 100644
index 0000000..453fb8d
--- /dev/null
+++ b/rspec-expectations/features/test_frameworks/minitest.feature
@@ -0,0 +1,44 @@
+Feature: Minitest integration
+
+  rspec-expectations is a stand-alone gem that can be used without the rest of RSpec. If you
+  like minitest as your test runner, but prefer RSpec's approach to expressing expectations,
+  you can have both.
+
+  To integrate rspec-expectations with minitest, require `rspec/expectations/minitest_integration`.
+
+  Scenario: use rspec/expectations with minitest
+    Given a file named "rspec_expectations_test.rb" with:
+      """ruby
+      require 'minitest/autorun'
+      require 'rspec/expectations/minitest_integration'
+
+      class RSpecExpectationsTest < Minitest::Test
+        RSpec::Matchers.define :be_an_integer do
+          match { |actual| Integer === actual }
+        end
+
+        def be_an_int
+          # This is actually an internal rspec-expectations API, but is used
+          # here to demonstrate that deprecation warnings from within
+          # rspec-expectations work correcty without depending on rspec-core
+          RSpec.deprecate(:be_an_int, :replacement => :be_an_integer)
+          be_an_integer
+        end
+
+        def test_passing_expectation
+          expect(1 + 3).to eq 4
+        end
+
+        def test_failing_expectation
+          expect([1, 2]).to be_empty
+        end
+
+        def test_custom_matcher_with_deprecation_warning
+          expect(1).to be_an_int
+        end
+      end
+      """
+     When I run `ruby rspec_expectations_test.rb`
+     Then the output should contain "3 runs, 3 assertions, 1 failures, 0 errors"
+      And the output should contain "expected `[1, 2].empty?` to return true, got false"
+      And the output should contain "be_an_int is deprecated"
diff --git a/rspec-expectations/lib/rspec/expectations.rb b/rspec-expectations/lib/rspec/expectations.rb
new file mode 100644
index 0000000..604e70b
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations.rb
@@ -0,0 +1,69 @@
+require 'rspec/support'
+RSpec::Support.require_rspec_support "caller_filter"
+RSpec::Support.require_rspec_support "warnings"
+
+require 'rspec/matchers'
+
+RSpec::Support.define_optimized_require_for_rspec(:expectations) { |f| require_relative(f) }
+
+%w[
+  expectation_target
+  configuration
+  fail_with
+  handler
+  version
+].each { |file| RSpec::Support.require_rspec_expectations(file) }
+
+module RSpec
+  # RSpec::Expectations provides a simple, readable API to express
+  # the expected outcomes in a code example. To express an expected
+  # outcome, wrap an object or block in `expect`, call `to` or `to_not`
+  # (aliased as `not_to`) and pass it a matcher object:
+  #
+  #     expect(order.total).to eq(Money.new(5.55, :USD))
+  #     expect(list).to include(user)
+  #     expect(message).not_to match(/foo/)
+  #     expect { do_something }.to raise_error
+  #
+  # The last form (the block form) is needed to match against ruby constructs
+  # that are not objects, but can only be observed when executing a block
+  # of code. This includes raising errors, throwing symbols, yielding,
+  # and changing values.
+  #
+  # When `expect(...).to` is invoked with a matcher, it turns around
+  # and calls `matcher.matches?(<object wrapped by expect>)`.  For example,
+  # in the expression:
+  #
+  #     expect(order.total).to eq(Money.new(5.55, :USD))
+  #
+  # ...`eq(Money.new(5.55, :USD))` returns a matcher object, and it results
+  # in the equivalent of `eq.matches?(order.total)`. If `matches?` returns
+  # `true`, the expectation is met and execution continues. If `false`, then
+  # the spec fails with the message returned by `eq.failure_message`.
+  #
+  # Given the expression:
+  #
+  #     expect(order.entries).not_to include(entry)
+  #
+  # ...the `not_to` method (also available as `to_not`) invokes the equivalent of
+  # `include.matches?(order.entries)`, but it interprets `false` as success, and
+  # `true` as a failure, using the message generated by
+  # `include.failure_message_when_negated`.
+  #
+  # rspec-expectations ships with a standard set of useful matchers, and writing
+  # your own matchers is quite simple.
+  #
+  # See [RSpec::Matchers](../RSpec/Matchers) for more information about the
+  # built-in matchers that ship with rspec-expectations, and how to write your
+  # own custom matchers.
+  module Expectations
+    # Exception raised when an expectation fails.
+    #
+    # @note We subclass Exception so that in a stub implementation if
+    # the user sets an expectation, it can't be caught in their
+    # code by a bare `rescue`.
+    # @api public
+    class ExpectationNotMetError < ::Exception
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/configuration.rb b/rspec-expectations/lib/rspec/expectations/configuration.rb
new file mode 100644
index 0000000..956ef18
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/configuration.rb
@@ -0,0 +1,147 @@
+RSpec::Support.require_rspec_expectations "syntax"
+
+module RSpec
+  module Expectations
+    # Provides configuration options for rspec-expectations.
+    # If you are using rspec-core, you can access this via a
+    # block passed to `RSpec::Core::Configuration#expect_with`.
+    # Otherwise, you can access it via RSpec::Expectations.configuration.
+    #
+    # @example
+    #   RSpec.configure do |rspec|
+    #     rspec.expect_with :rspec do |c|
+    #       # c is the config object
+    #     end
+    #   end
+    #
+    #   # or
+    #
+    #   RSpec::Expectations.configuration
+    class Configuration
+      # Configures the supported syntax.
+      # @param [Array<Symbol>, Symbol] values the syntaxes to enable
+      # @example
+      #   RSpec.configure do |rspec|
+      #     rspec.expect_with :rspec do |c|
+      #       c.syntax = :should
+      #       # or
+      #       c.syntax = :expect
+      #       # or
+      #       c.syntax = [:should, :expect]
+      #     end
+      #   end
+      def syntax=(values)
+        if Array(values).include?(:expect)
+          Expectations::Syntax.enable_expect
+        else
+          Expectations::Syntax.disable_expect
+        end
+
+        if Array(values).include?(:should)
+          Expectations::Syntax.enable_should
+        else
+          Expectations::Syntax.disable_should
+        end
+      end
+
+      # The list of configured syntaxes.
+      # @return [Array<Symbol>] the list of configured syntaxes.
+      # @example
+      #   unless RSpec::Matchers.configuration.syntax.include?(:expect)
+      #     raise "this RSpec extension gem requires the rspec-expectations `:expect` syntax"
+      #   end
+      def syntax
+        syntaxes = []
+        syntaxes << :should if Expectations::Syntax.should_enabled?
+        syntaxes << :expect if Expectations::Syntax.expect_enabled?
+        syntaxes
+      end
+
+      if ::RSpec.respond_to?(:configuration)
+        def color?
+          ::RSpec.configuration.color_enabled?
+        end
+      else
+        # Indicates whether or not diffs should be colored.
+        # Delegates to rspec-core's color option if rspec-core
+        # is loaded; otherwise you can set it here.
+        attr_writer :color
+
+        # Indicates whether or not diffs should be colored.
+        # Delegates to rspec-core's color option if rspec-core
+        # is loaded; otherwise you can set it here.
+        def color?
+          defined?(@color) && @color
+        end
+      end
+
+      # Adds `should` and `should_not` to the given classes
+      # or modules. This can be used to ensure `should` works
+      # properly on things like proxy objects (particular
+      # `Delegator`-subclassed objects on 1.8).
+      #
+      # @param [Array<Module>] modules the list of classes or modules
+      #   to add `should` and `should_not` to.
+      def add_should_and_should_not_to(*modules)
+        modules.each do |mod|
+          Expectations::Syntax.enable_should(mod)
+        end
+      end
+
+      # Sets or gets the backtrace formatter. The backtrace formatter should
+      # implement `#format_backtrace(Array<String>)`. This is used
+      # to format backtraces of errors handled by the `raise_error`
+      # matcher.
+      #
+      # If you are using rspec-core, rspec-core's backtrace formatting
+      # will be used (including respecting the presence or absence of
+      # the `--backtrace` option).
+      #
+      # @!attribute [rw] backtrace_formatter
+      attr_writer :backtrace_formatter
+      def backtrace_formatter
+        @backtrace_formatter ||= if defined?(::RSpec.configuration.backtrace_formatter)
+                                   ::RSpec.configuration.backtrace_formatter
+                                 else
+                                   NullBacktraceFormatter
+                                 end
+      end
+
+      # Sets if custom matcher descriptions and failure messages
+      # should include clauses from methods defined using `chain`.
+      # @param value [Boolean]
+      attr_writer :include_chain_clauses_in_custom_matcher_descriptions
+
+      # Indicates whether or not custom matcher descriptions and failure messages
+      # should include clauses from methods defined using `chain`. It is
+      # false by default for backwards compatibility.
+      def include_chain_clauses_in_custom_matcher_descriptions?
+        @include_chain_clauses_in_custom_matcher_descriptions ||= false
+      end
+
+      # @private
+      def reset_syntaxes_to_default
+        self.syntax = [:should, :expect]
+        RSpec::Expectations::Syntax.warn_about_should!
+      end
+
+      # @api private
+      # Null implementation of a backtrace formatter used by default
+      # when rspec-core is not loaded. Does no filtering.
+      NullBacktraceFormatter = Module.new do
+        def self.format_backtrace(backtrace)
+          backtrace
+        end
+      end
+    end
+
+    # The configuration object.
+    # @return [RSpec::Expectations::Configuration] the configuration object
+    def self.configuration
+      @configuration ||= Configuration.new
+    end
+
+    # set default syntax
+    configuration.reset_syntaxes_to_default
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/expectation_target.rb b/rspec-expectations/lib/rspec/expectations/expectation_target.rb
new file mode 100644
index 0000000..cc74c19
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/expectation_target.rb
@@ -0,0 +1,119 @@
+module RSpec
+  module Expectations
+    # Wraps the target of an expectation.
+    #
+    # @example
+    #   expect(something)       # => ExpectationTarget wrapping something
+    #   expect { do_something } # => ExpectationTarget wrapping the block
+    #
+    #   # used with `to`
+    #   expect(actual).to eq(3)
+    #
+    #   # with `not_to`
+    #   expect(actual).not_to eq(3)
+    #
+    # @note `ExpectationTarget` is not intended to be instantiated
+    #   directly by users. Use `expect` instead.
+    class ExpectationTarget
+      # @private
+      # Used as a sentinel value to be able to tell when the user
+      # did not pass an argument. We can't use `nil` for that because
+      # `nil` is a valid value to pass.
+      UndefinedValue = Module.new
+
+      # @api private
+      def initialize(value)
+        @target = value
+      end
+
+      # @private
+      def self.for(value, block)
+        if UndefinedValue.equal?(value)
+          unless block
+            raise ArgumentError, "You must pass either an argument or a block to `expect`."
+          end
+          BlockExpectationTarget.new(block)
+        elsif block
+          raise ArgumentError, "You cannot pass both an argument and a block to `expect`."
+        else
+          new(value)
+        end
+      end
+
+      # Runs the given expectation, passing if `matcher` returns true.
+      # @example
+      #   expect(value).to eq(5)
+      #   expect { perform }.to raise_error
+      # @param [Matcher]
+      #   matcher
+      # @param [String or Proc] message optional message to display when the expectation fails
+      # @return [Boolean] true if the expectation succeeds (else raises)
+      # @see RSpec::Matchers
+      def to(matcher=nil, message=nil, &block)
+        prevent_operator_matchers(:to) unless matcher
+        RSpec::Expectations::PositiveExpectationHandler.handle_matcher(@target, matcher, message, &block)
+      end
+
+      # Runs the given expectation, passing if `matcher` returns false.
+      # @example
+      #   expect(value).not_to eq(5)
+      # @param [Matcher]
+      #   matcher
+      # @param [String or Proc] message optional message to display when the expectation fails
+      # @return [Boolean] false if the negative expectation succeeds (else raises)
+      # @see RSpec::Matchers
+      def not_to(matcher=nil, message=nil, &block)
+        prevent_operator_matchers(:not_to) unless matcher
+        RSpec::Expectations::NegativeExpectationHandler.handle_matcher(@target, matcher, message, &block)
+      end
+      alias to_not not_to
+
+    private
+
+      def prevent_operator_matchers(verb)
+        raise ArgumentError, "The expect syntax does not support operator matchers, " \
+                             "so you must pass a matcher to `##{verb}`."
+      end
+    end
+
+    # @private
+    # Validates the provided matcher to ensure it supports block
+    # expectations, in order to avoid user confusion when they
+    # use a block thinking the expectation will be on the return
+    # value of the block rather than the block itself.
+    class BlockExpectationTarget < ExpectationTarget
+      def to(matcher, message=nil, &block)
+        enforce_block_expectation(matcher)
+        super
+      end
+
+      def not_to(matcher, message=nil, &block)
+        enforce_block_expectation(matcher)
+        super
+      end
+      alias to_not not_to
+
+    private
+
+      def enforce_block_expectation(matcher)
+        return if supports_block_expectations?(matcher)
+
+        raise ExpectationNotMetError, "You must pass an argument rather than " \
+          "a block to use the provided matcher (#{description_of matcher}), or " \
+          "the matcher must implement `supports_block_expectations?`."
+      end
+
+      def supports_block_expectations?(matcher)
+        matcher.supports_block_expectations?
+      rescue NoMethodError
+        false
+      end
+
+      def description_of(matcher)
+        matcher.description
+      rescue NoMethodError
+        matcher.inspect
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/fail_with.rb b/rspec-expectations/lib/rspec/expectations/fail_with.rb
new file mode 100644
index 0000000..e41236e
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/fail_with.rb
@@ -0,0 +1,33 @@
+RSpec::Support.require_rspec_support 'differ'
+
+module RSpec
+  module Expectations
+    class << self
+      # @private
+      def differ
+        RSpec::Support::Differ.new(
+          :object_preparer => lambda { |object| RSpec::Matchers::Composable.surface_descriptions_in(object) },
+          :color => RSpec::Matchers.configuration.color?
+        )
+      end
+
+      # Raises an RSpec::Expectations::ExpectationNotMetError with message.
+      # @param [String] message
+      # @param [Object] expected
+      # @param [Object] actual
+      #
+      # Adds a diff to the failure message when `expected` and `actual` are
+      # both present.
+      def fail_with(message, expected=nil, actual=nil)
+        unless message
+          raise ArgumentError, "Failure message is nil. Does your matcher define the " \
+                               "appropriate failure_message[_when_negated] method to return a string?"
+        end
+
+        message = ::RSpec::Matchers::ExpectedsForMultipleDiffs.from(expected).message_with_diff(message, differ, actual)
+
+        raise RSpec::Expectations::ExpectationNotMetError, message
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/handler.rb b/rspec-expectations/lib/rspec/expectations/handler.rb
new file mode 100644
index 0000000..afb571a
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/handler.rb
@@ -0,0 +1,170 @@
+module RSpec
+  module Expectations
+    # @private
+    module ExpectationHelper
+      def self.check_message(msg)
+        unless msg.nil? || msg.respond_to?(:to_str) || msg.respond_to?(:call)
+          ::Kernel.warn [
+            "WARNING: ignoring the provided expectation message argument (",
+            msg.inspect,
+            ") since it is not a string or a proc."
+          ].join
+        end
+      end
+
+      # Returns an RSpec-3+ compatible matcher, wrapping a legacy one
+      # in an adapter if necessary.
+      #
+      # @private
+      def self.modern_matcher_from(matcher)
+        LegacyMatcherAdapter::RSpec2.wrap(matcher) ||
+        LegacyMatcherAdapter::RSpec1.wrap(matcher) || matcher
+      end
+
+      def self.with_matcher(handler, matcher, message)
+        check_message(message)
+        matcher = modern_matcher_from(matcher)
+        yield matcher
+      ensure
+        ::RSpec::Matchers.last_expectation_handler = handler
+        ::RSpec::Matchers.last_matcher = matcher
+      end
+
+      def self.handle_failure(matcher, message, failure_message_method)
+        message = message.call if message.respond_to?(:call)
+        message ||= matcher.__send__(failure_message_method)
+
+        if matcher.respond_to?(:diffable?) && matcher.diffable?
+          ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual
+        else
+          ::RSpec::Expectations.fail_with message
+        end
+      end
+    end
+
+    # @private
+    class PositiveExpectationHandler
+      def self.handle_matcher(actual, initial_matcher, message=nil, &block)
+        ExpectationHelper.with_matcher(self, initial_matcher, message) do |matcher|
+          return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher
+          matcher.matches?(actual, &block) || ExpectationHelper.handle_failure(matcher, message, :failure_message)
+        end
+      end
+
+      def self.verb
+        "should"
+      end
+
+      def self.should_method
+        :should
+      end
+
+      def self.opposite_should_method
+        :should_not
+      end
+    end
+
+    # @private
+    class NegativeExpectationHandler
+      def self.handle_matcher(actual, initial_matcher, message=nil, &block)
+        ExpectationHelper.with_matcher(self, initial_matcher, message) do |matcher|
+          return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher
+          !(does_not_match?(matcher, actual, &block) || ExpectationHelper.handle_failure(matcher, message, :failure_message_when_negated))
+        end
+      end
+
+      def self.does_not_match?(matcher, actual, &block)
+        if matcher.respond_to?(:does_not_match?)
+          matcher.does_not_match?(actual, &block)
+        else
+          !matcher.matches?(actual, &block)
+        end
+      end
+
+      def self.verb
+        "should not"
+      end
+
+      def self.should_method
+        :should_not
+      end
+
+      def self.opposite_should_method
+        :should
+      end
+    end
+
+    # Wraps a matcher written against one of the legacy protocols in
+    # order to present the current protocol.
+    #
+    # @private
+    class LegacyMatcherAdapter < Matchers::MatcherDelegator
+      def initialize(matcher)
+        super
+        ::RSpec.warn_deprecation(<<-EOS.gsub(/^\s+\|/, ''), :type => "legacy_matcher")
+          |#{matcher.class.name || matcher.inspect} implements a legacy RSpec matcher
+          |protocol. For the current protocol you should expose the failure messages
+          |via the `failure_message` and `failure_message_when_negated` methods.
+          |(Used from #{CallerFilter.first_non_rspec_line})
+        EOS
+      end
+
+      def self.wrap(matcher)
+        new(matcher) if interface_matches?(matcher)
+      end
+
+      # Starting in RSpec 1.2 (and continuing through all 2.x releases),
+      # the failure message protocol was:
+      #   * `failure_message_for_should`
+      #   * `failure_message_for_should_not`
+      # @private
+      class RSpec2 < self
+        def failure_message
+          base_matcher.failure_message_for_should
+        end
+
+        def failure_message_when_negated
+          base_matcher.failure_message_for_should_not
+        end
+
+        def self.interface_matches?(matcher)
+          (
+            !matcher.respond_to?(:failure_message) &&
+            matcher.respond_to?(:failure_message_for_should)
+          ) || (
+            !matcher.respond_to?(:failure_message_when_negated) &&
+            matcher.respond_to?(:failure_message_for_should_not)
+          )
+        end
+      end
+
+      # Before RSpec 1.2, the failure message protocol was:
+      #   * `failure_message`
+      #   * `negative_failure_message`
+      # @private
+      class RSpec1 < self
+        def failure_message
+          base_matcher.failure_message
+        end
+
+        def failure_message_when_negated
+          base_matcher.negative_failure_message
+        end
+
+        # Note: `failure_message` is part of the RSpec 3 protocol
+        # (paired with `failure_message_when_negated`), so we don't check
+        # for `failure_message` here.
+        def self.interface_matches?(matcher)
+          !matcher.respond_to?(:failure_message_when_negated) &&
+          matcher.respond_to?(:negative_failure_message)
+        end
+      end
+    end
+
+    # RSpec 3.0 was released with the class name misspelled. For SemVer compatibility,
+    # we will provide this misspelled alias until 4.0.
+    # @deprecated Use LegacyMatcherAdapter instead.
+    # @private
+    LegacyMacherAdapter = LegacyMatcherAdapter
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/minitest_integration.rb b/rspec-expectations/lib/rspec/expectations/minitest_integration.rb
new file mode 100644
index 0000000..fb5bdc8
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/minitest_integration.rb
@@ -0,0 +1,18 @@
+require 'rspec/expectations'
+
+Minitest::Test.class_eval do
+  include ::RSpec::Matchers
+
+  def expect(*a, &b)
+    assert(true) # so each expectation gets counted in minitest's assertion stats
+    super
+  end
+end
+
+module RSpec
+  module Expectations
+    remove_const :ExpectationNotMetError
+    # Exception raised when an expectation fails.
+    ExpectationNotMetError = ::Minitest::Assertion
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/syntax.rb b/rspec-expectations/lib/rspec/expectations/syntax.rb
new file mode 100644
index 0000000..f2fc442
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/syntax.rb
@@ -0,0 +1,132 @@
+module RSpec
+  module Expectations
+    # @api private
+    # Provides methods for enabling and disabling the available
+    # syntaxes provided by rspec-expectations.
+    module Syntax
+      module_function
+
+      # @api private
+      # Determines where we add `should` and `should_not`.
+      def default_should_host
+        @default_should_host ||= ::Object.ancestors.last
+      end
+
+      # @api private
+      # Instructs rspec-expectations to warn on first usage of `should` or `should_not`.
+      # Enabled by default. This is largely here to facilitate testing.
+      def warn_about_should!
+        @warn_about_should = true
+      end
+
+      # @api private
+      # Generates a deprecation warning for the given method if no warning
+      # has already been issued.
+      def warn_about_should_unless_configured(method_name)
+        return unless @warn_about_should
+
+        RSpec.deprecate(
+          "Using `#{method_name}` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax",
+          :replacement => "the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`"
+        )
+
+        @warn_about_should = false
+      end
+
+      # @api private
+      # Enables the `should` syntax.
+      def enable_should(syntax_host=default_should_host)
+        @warn_about_should = false if syntax_host == default_should_host
+        return if should_enabled?(syntax_host)
+
+        syntax_host.module_exec do
+          def should(matcher=nil, message=nil, &block)
+            ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(__method__)
+            ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block)
+          end
+
+          def should_not(matcher=nil, message=nil, &block)
+            ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(__method__)
+            ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block)
+          end
+        end
+      end
+
+      # @api private
+      # Disables the `should` syntax.
+      def disable_should(syntax_host=default_should_host)
+        return unless should_enabled?(syntax_host)
+
+        syntax_host.module_exec do
+          undef should
+          undef should_not
+        end
+      end
+
+      # @api private
+      # Enables the `expect` syntax.
+      def enable_expect(syntax_host=::RSpec::Matchers)
+        return if expect_enabled?(syntax_host)
+
+        syntax_host.module_exec do
+          def expect(value=::RSpec::Expectations::ExpectationTarget::UndefinedValue, &block)
+            ::RSpec::Expectations::ExpectationTarget.for(value, block)
+          end
+        end
+      end
+
+      # @api private
+      # Disables the `expect` syntax.
+      def disable_expect(syntax_host=::RSpec::Matchers)
+        return unless expect_enabled?(syntax_host)
+
+        syntax_host.module_exec do
+          undef expect
+        end
+      end
+
+      # @api private
+      # Indicates whether or not the `should` syntax is enabled.
+      def should_enabled?(syntax_host=default_should_host)
+        syntax_host.method_defined?(:should)
+      end
+
+      # @api private
+      # Indicates whether or not the `expect` syntax is enabled.
+      def expect_enabled?(syntax_host=::RSpec::Matchers)
+        syntax_host.method_defined?(:expect)
+      end
+    end
+  end
+end
+
+if defined?(BasicObject)
+  # The legacy `:should` syntax adds the following methods directly to
+  # `BasicObject` so that they are available off of any object. Note, however,
+  # that this syntax does not always play nice with delegate/proxy objects.
+  # We recommend you use the non-monkeypatching `:expect` syntax instead.
+  class BasicObject
+    # @method should
+    # Passes if `matcher` returns true.  Available on every `Object`.
+    # @example
+    #   actual.should eq expected
+    #   actual.should match /expression/
+    # @param [Matcher]
+    #   matcher
+    # @param [String] message optional message to display when the expectation fails
+    # @return [Boolean] true if the expectation succeeds (else raises)
+    # @note This is only available when you have enabled the `:should` syntax.
+    # @see RSpec::Matchers
+
+    # @method should_not
+    # Passes if `matcher` returns false.  Available on every `Object`.
+    # @example
+    #   actual.should_not eq expected
+    # @param [Matcher]
+    #   matcher
+    # @param [String] message optional message to display when the expectation fails
+    # @return [Boolean] false if the negative expectation succeeds (else raises)
+    # @note This is only available when you have enabled the `:should` syntax.
+    # @see RSpec::Matchers
+  end
+end
diff --git a/rspec-expectations/lib/rspec/expectations/version.rb b/rspec-expectations/lib/rspec/expectations/version.rb
new file mode 100644
index 0000000..208741b
--- /dev/null
+++ b/rspec-expectations/lib/rspec/expectations/version.rb
@@ -0,0 +1,8 @@
+module RSpec
+  module Expectations
+    # @private
+    module Version
+      STRING = '3.2.0'
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers.rb b/rspec-expectations/lib/rspec/matchers.rb
new file mode 100644
index 0000000..700361d
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers.rb
@@ -0,0 +1,955 @@
+require 'rspec/support'
+RSpec::Support.require_rspec_support 'matcher_definition'
+RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relative(f) }
+
+%w[
+  pretty
+  composable
+  built_in
+  generated_descriptions
+  dsl
+  matcher_delegator
+  aliased_matcher
+  expecteds_for_multiple_diffs
+].each { |file| RSpec::Support.require_rspec_matchers(file) }
+
+# RSpec's top level namespace. All of rspec-expectations is contained
+# in the `RSpec::Expectations` and `RSpec::Matchers` namespaces.
+module RSpec
+  # RSpec::Matchers provides a number of useful matchers we use to define
+  # expectations. Any object that implements the [matcher protocol](Matchers/MatcherProtocol)
+  # can be used as a matcher.
+  #
+  # ## Predicates
+  #
+  # In addition to matchers that are defined explicitly, RSpec will create
+  # custom matchers on the fly for any arbitrary predicate, giving your specs a
+  # much more natural language feel.
+  #
+  # A Ruby predicate is a method that ends with a "?" and returns true or false.
+  # Common examples are `empty?`, `nil?`, and `instance_of?`.
+  #
+  # All you need to do is write `expect(..).to be_` followed by the predicate
+  # without the question mark, and RSpec will figure it out from there.
+  # For example:
+  #
+  #     expect([]).to be_empty     # => [].empty?() | passes
+  #     expect([]).not_to be_empty # => [].empty?() | fails
+  #
+  # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
+  # and "be_an_", making your specs read much more naturally:
+  #
+  #     expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes
+  #
+  #     expect(3).to be_a_kind_of(Fixnum)        # => 3.kind_of?(Numeric)     | passes
+  #     expect(3).to be_a_kind_of(Numeric)       # => 3.kind_of?(Numeric)     | passes
+  #     expect(3).to be_an_instance_of(Fixnum)   # => 3.instance_of?(Fixnum)  | passes
+  #     expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails
+  #
+  # RSpec will also create custom matchers for predicates like `has_key?`. To
+  # use this feature, just state that the object should have_key(:key) and RSpec will
+  # call has_key?(:key) on the target. For example:
+  #
+  #     expect(:a => "A").to have_key(:a)
+  #     expect(:a => "A").to have_key(:b) # fails
+  #
+  # You can use this feature to invoke any predicate that begins with "has_", whether it is
+  # part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class.
+  #
+  # Note that RSpec does not provide composable aliases for these dynamic predicate
+  # matchers. You can easily define your own aliases, though:
+  #
+  #     RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin
+  #     expect(user_list).to include(a_user_who_is_an_admin)
+  #
+  # ## Custom Matchers
+  #
+  # When you find that none of the stock matchers provide a natural feeling
+  # expectation, you can very easily write your own using RSpec's matcher DSL
+  # or writing one from scratch.
+  #
+  # ### Matcher DSL
+  #
+  # Imagine that you are writing a game in which players can be in various
+  # zones on a virtual board. To specify that bob should be in zone 4, you
+  # could say:
+  #
+  #     expect(bob.current_zone).to eql(Zone.new("4"))
+  #
+  # But you might find it more expressive to say:
+  #
+  #     expect(bob).to be_in_zone("4")
+  #
+  # and/or
+  #
+  #     expect(bob).not_to be_in_zone("3")
+  #
+  # You can create such a matcher like so:
+  #
+  #     RSpec::Matchers.define :be_in_zone do |zone|
+  #       match do |player|
+  #         player.in_zone?(zone)
+  #       end
+  #     end
+  #
+  # This will generate a <tt>be_in_zone</tt> method that returns a matcher
+  # with logical default messages for failures. You can override the failure
+  # messages and the generated description as follows:
+  #
+  #     RSpec::Matchers.define :be_in_zone do |zone|
+  #       match do |player|
+  #         player.in_zone?(zone)
+  #       end
+  #
+  #       failure_message do |player|
+  #         # generate and return the appropriate string.
+  #       end
+  #
+  #       failure_message_when_negated do |player|
+  #         # generate and return the appropriate string.
+  #       end
+  #
+  #       description do
+  #         # generate and return the appropriate string.
+  #       end
+  #     end
+  #
+  # Each of the message-generation methods has access to the block arguments
+  # passed to the <tt>create</tt> method (in this case, <tt>zone</tt>). The
+  # failure message methods (<tt>failure_message</tt> and
+  # <tt>failure_message_when_negated</tt>) are passed the actual value (the
+  # receiver of <tt>expect(..)</tt> or <tt>expect(..).not_to</tt>).
+  #
+  # ### Custom Matcher from scratch
+  #
+  # You could also write a custom matcher from scratch, as follows:
+  #
+  #     class BeInZone
+  #       def initialize(expected)
+  #         @expected = expected
+  #       end
+  #
+  #       def matches?(target)
+  #         @target = target
+  #         @target.current_zone.eql?(Zone.new(@expected))
+  #       end
+  #
+  #       def failure_message
+  #         "expected #{@target.inspect} to be in Zone #{@expected}"
+  #       end
+  #
+  #       def failure_message_when_negated
+  #         "expected #{@target.inspect} not to be in Zone #{@expected}"
+  #       end
+  #     end
+  #
+  # ... and a method like this:
+  #
+  #     def be_in_zone(expected)
+  #       BeInZone.new(expected)
+  #     end
+  #
+  # And then expose the method to your specs. This is normally done
+  # by including the method and the class in a module, which is then
+  # included in your spec:
+  #
+  #     module CustomGameMatchers
+  #       class BeInZone
+  #         # ...
+  #       end
+  #
+  #       def be_in_zone(expected)
+  #         # ...
+  #       end
+  #     end
+  #
+  #     describe "Player behaviour" do
+  #       include CustomGameMatchers
+  #       # ...
+  #     end
+  #
+  # or you can include in globally in a spec_helper.rb file <tt>require</tt>d
+  # from your spec file(s):
+  #
+  #     RSpec::configure do |config|
+  #       config.include(CustomGameMatchers)
+  #     end
+  #
+  # ### Making custom matchers composable
+  #
+  # RSpec's built-in matchers are designed to be composed, in expressions like:
+  #
+  #     expect(["barn", 2.45]).to contain_exactly(
+  #       a_value_within(0.1).of(2.5),
+  #       a_string_starting_with("bar")
+  #     )
+  #
+  # Custom matchers can easily participate in composed matcher expressions like these.
+  # Include {RSpec::Matchers::Composable} in your custom matcher to make it support
+  # being composed (matchers defined using the DSL have this included automatically).
+  # Within your matcher's `matches?` method (or the `match` block, if using the DSL),
+  # use `values_match?(expected, actual)` rather than `expected == actual`.
+  # Under the covers, `values_match?` is able to match arbitrary
+  # nested data structures containing a mix of both matchers and non-matcher objects.
+  # It uses `===` and `==` to perform the matching, considering the values to
+  # match if either returns `true`. The `Composable` mixin also provides some helper
+  # methods for surfacing the matcher descriptions within your matcher's description
+  # or failure messages.
+  #
+  # RSpec's built-in matchers each have a number of aliases that rephrase the matcher
+  # from a verb phrase (such as `be_within`) to a noun phrase (such as `a_value_within`),
+  # which reads better when the matcher is passed as an argument in a composed matcher
+  # expressions, and also uses the noun-phrase wording in the matcher's `description`,
+  # for readable failure messages. You can alias your custom matchers in similar fashion
+  # using {RSpec::Matchers.alias_matcher}.
+  module Matchers
+    # @method expect
+    # Supports `expect(actual).to matcher` syntax by wrapping `actual` in an
+    # `ExpectationTarget`.
+    # @example
+    #   expect(actual).to eq(expected)
+    #   expect(actual).not_to eq(expected)
+    # @return [ExpectationTarget]
+    # @see ExpectationTarget#to
+    # @see ExpectationTarget#not_to
+
+    # Defines a matcher alias. The returned matcher's `description` will be overriden
+    # to reflect the phrasing of the new name, which will be used in failure messages
+    # when passed as an argument to another matcher in a composed matcher expression.
+    #
+    # @param new_name [Symbol] the new name for the matcher
+    # @param old_name [Symbol] the original name for the matcher
+    # @param options  [Hash] options for the aliased matcher
+    # @option options [Class] :klass the ruby class to use as the decorator. (Not normally used).
+    # @yield [String] optional block that, when given, is used to define the overriden
+    #   logic. The yielded arg is the original description or failure message. If no
+    #   block is provided, a default override is used based on the old and new names.
+    #
+    # @example
+    #   RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to
+    #   sum_to(3).description # => "sum to 3"
+    #   a_list_that_sums_to(3).description # => "a list that sums to 3"
+    #
+    # @example
+    #   RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description|
+    #     description.sub("be sorted by", "a list sorted by")
+    #   end
+    #
+    #   be_sorted_by(:age).description # => "be sorted by age"
+    #   a_list_sorted_by(:age).description # => "a list sorted by age"
+    #
+    # @!macro [attach] alias_matcher
+    #   @!parse
+    #     alias $1 $2
+    def self.alias_matcher(new_name, old_name, options={}, &description_override)
+      description_override ||= lambda do |old_desc|
+        old_desc.gsub(Pretty.split_words(old_name), Pretty.split_words(new_name))
+      end
+      klass = options.fetch(:klass) { AliasedMatcher }
+
+      define_method(new_name) do |*args, &block|
+        matcher = __send__(old_name, *args, &block)
+        klass.new(matcher, description_override)
+      end
+    end
+
+    # Defines a negated matcher. The returned matcher's `description` and `failure_message`
+    # will be overriden to reflect the phrasing of the new name, and the match logic will
+    # be based on the original matcher but negated.
+    #
+    # @param negated_name [Symbol] the name for the negated matcher
+    # @param base_name [Symbol] the name of the original matcher that will be negated
+    # @yield [String] optional block that, when given, is used to define the overriden
+    #   logic. The yielded arg is the original description or failure message. If no
+    #   block is provided, a default override is used based on the old and new names.
+    #
+    # @example
+    #   RSpec::Matchers.define_negated_matcher :exclude, :include
+    #   include(1, 2).description # => "include 1 and 2"
+    #   exclude(1, 2).description # => "exclude 1 and 2"
+    #
+    # @note While the most obvious negated form may be to add a `not_` prefix,
+    #   the failure messages you get with that form can be confusing (e.g.
+    #   "expected [actual] to not [verb], but did not"). We've found it works
+    #   best to find a more positive name for the negated form, such as
+    #   `avoid_changing` rather than `not_change`.
+    def self.define_negated_matcher(negated_name, base_name, &description_override)
+      alias_matcher(negated_name, base_name, :klass => AliasedNegatedMatcher, &description_override)
+    end
+
+    # Passes if actual is truthy (anything but false or nil)
+    def be_truthy
+      BuiltIn::BeTruthy.new
+    end
+    alias_matcher :a_truthy_value, :be_truthy
+
+    # Passes if actual is falsey (false or nil)
+    def be_falsey
+      BuiltIn::BeFalsey.new
+    end
+    alias_matcher :be_falsy,       :be_falsey
+    alias_matcher :a_falsey_value, :be_falsey
+    alias_matcher :a_falsy_value,  :be_falsey
+
+    # Passes if actual is nil
+    def be_nil
+      BuiltIn::BeNil.new
+    end
+    alias_matcher :a_nil_value, :be_nil
+
+    # @example
+    #   expect(actual).to     be_truthy
+    #   expect(actual).to     be_falsey
+    #   expect(actual).to     be_nil
+    #   expect(actual).to     be_[arbitrary_predicate](*args)
+    #   expect(actual).not_to be_nil
+    #   expect(actual).not_to be_[arbitrary_predicate](*args)
+    #
+    # Given true, false, or nil, will pass if actual value is true, false or
+    # nil (respectively). Given no args means the caller should satisfy an if
+    # condition (to be or not to be).
+    #
+    # Predicates are any Ruby method that ends in a "?" and returns true or
+    # false.  Given be_ followed by arbitrary_predicate (without the "?"),
+    # RSpec will match convert that into a query against the target object.
+    #
+    # The arbitrary_predicate feature will handle any predicate prefixed with
+    # "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of) or "be_"
+    # (e.g. be_empty), letting you choose the prefix that best suits the
+    # predicate.
+    def be(*args)
+      args.empty? ? Matchers::BuiltIn::Be.new : equal(*args)
+    end
+    alias_matcher :a_value, :be, :klass => AliasedMatcherWithOperatorSupport
+
+    # passes if target.kind_of?(klass)
+    def be_a(klass)
+      be_a_kind_of(klass)
+    end
+    alias_method :be_an, :be_a
+
+    # Passes if actual.instance_of?(expected)
+    #
+    # @example
+    #   expect(5).to     be_an_instance_of(Fixnum)
+    #   expect(5).not_to be_an_instance_of(Numeric)
+    #   expect(5).not_to be_an_instance_of(Float)
+    def be_an_instance_of(expected)
+      BuiltIn::BeAnInstanceOf.new(expected)
+    end
+    alias_method :be_instance_of, :be_an_instance_of
+    alias_matcher :an_instance_of, :be_an_instance_of
+
+    # Passes if actual.kind_of?(expected)
+    #
+    # @example
+    #   expect(5).to     be_a_kind_of(Fixnum)
+    #   expect(5).to     be_a_kind_of(Numeric)
+    #   expect(5).not_to be_a_kind_of(Float)
+    def be_a_kind_of(expected)
+      BuiltIn::BeAKindOf.new(expected)
+    end
+    alias_method :be_kind_of, :be_a_kind_of
+    alias_matcher :a_kind_of,  :be_a_kind_of
+
+    # Passes if actual.between?(min, max). Works with any Comparable object,
+    # including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer,
+    # Float, Complex, and Rational).
+    #
+    # By default, `be_between` is inclusive (i.e. passes when given either the max or min value),
+    # but you can make it `exclusive` by chaining that off the matcher.
+    #
+    # @example
+    #   expect(5).to      be_between(1, 10)
+    #   expect(11).not_to be_between(1, 10)
+    #   expect(10).not_to be_between(1, 10).exclusive
+    def be_between(min, max)
+      BuiltIn::BeBetween.new(min, max)
+    end
+    alias_matcher :a_value_between, :be_between
+
+    # Passes if actual == expected +/- delta
+    #
+    # @example
+    #   expect(result).to     be_within(0.5).of(3.0)
+    #   expect(result).not_to be_within(0.5).of(3.0)
+    def be_within(delta)
+      BuiltIn::BeWithin.new(delta)
+    end
+    alias_matcher :a_value_within, :be_within
+    alias_matcher :within,         :be_within
+
+    # Applied to a proc, specifies that its execution will cause some value to
+    # change.
+    #
+    # @param [Object] receiver
+    # @param [Symbol] message the message to send the receiver
+    #
+    # You can either pass <tt>receiver</tt> and <tt>message</tt>, or a block,
+    # but not both.
+    #
+    # When passing a block, it must use the `{ ... }` format, not
+    # do/end, as `{ ... }` binds to the `change` method, whereas do/end
+    # would errantly bind to the `expect(..).to` or `expect(...).not_to` method.
+    #
+    # You can chain any of the following off of the end to specify details
+    # about the change:
+    #
+    # * `from`
+    # * `to`
+    #
+    # or any one of:
+    #
+    # * `by`
+    # * `by_at_least`
+    # * `by_at_most`
+    #
+    # @example
+    #   expect {
+    #     team.add_player(player)
+    #   }.to change(roster, :count)
+    #
+    #   expect {
+    #     team.add_player(player)
+    #   }.to change(roster, :count).by(1)
+    #
+    #   expect {
+    #     team.add_player(player)
+    #   }.to change(roster, :count).by_at_least(1)
+    #
+    #   expect {
+    #     team.add_player(player)
+    #   }.to change(roster, :count).by_at_most(1)
+    #
+    #   string = "string"
+    #   expect {
+    #     string.reverse!
+    #   }.to change { string }.from("string").to("gnirts")
+    #
+    #   string = "string"
+    #   expect {
+    #     string
+    #   }.not_to change { string }.from("string")
+    #
+    #   expect {
+    #     person.happy_birthday
+    #   }.to change(person, :birthday).from(32).to(33)
+    #
+    #   expect {
+    #     employee.develop_great_new_social_networking_app
+    #   }.to change(employee, :title).from("Mail Clerk").to("CEO")
+    #
+    #   expect {
+    #     doctor.leave_office
+    #   }.to change(doctor, :sign).from(/is in/).to(/is out/)
+    #
+    #   user = User.new(:type => "admin")
+    #   expect {
+    #     user.symbolize_type
+    #   }.to change(user, :type).from(String).to(Symbol)
+    #
+    # == Notes
+    #
+    # Evaluates `receiver.message` or `block` before and after it
+    # evaluates the block passed to `expect`.
+    #
+    # `expect( ... ).not_to change` supports the form that specifies `from`
+    # (which specifies what you expect the starting, unchanged value to be)
+    # but does not support forms with subsequent calls to `by`, `by_at_least`,
+    # `by_at_most` or `to`.
+    def change(receiver=nil, message=nil, &block)
+      BuiltIn::Change.new(receiver, message, &block)
+    end
+    alias_matcher :a_block_changing,  :change
+    alias_matcher :changing,          :change
+
+    # Passes if actual contains all of the expected regardless of order.
+    # This works for collections. Pass in multiple args and it will only
+    # pass if all args are found in collection.
+    #
+    # @note This is also available using the `=~` operator with `should`,
+    #       but `=~` is not supported with `expect`.
+    #
+    # @example
+    #   expect([1, 2, 3]).to contain_exactly(1, 2, 3)
+    #   expect([1, 2, 3]).to contain_exactly(1, 3, 2)
+    #
+    # @see #match_array
+    def contain_exactly(*items)
+      BuiltIn::ContainExactly.new(items)
+    end
+    alias_matcher :a_collection_containing_exactly, :contain_exactly
+    alias_matcher :containing_exactly,              :contain_exactly
+
+    # Passes if actual covers expected. This works for
+    # Ranges. You can also pass in multiple args
+    # and it will only pass if all args are found in Range.
+    #
+    # @example
+    #   expect(1..10).to     cover(5)
+    #   expect(1..10).to     cover(4, 6)
+    #   expect(1..10).to     cover(4, 6, 11) # fails
+    #   expect(1..10).not_to cover(11)
+    #   expect(1..10).not_to cover(5)        # fails
+    #
+    # ### Warning:: Ruby >= 1.9 only
+    def cover(*values)
+      BuiltIn::Cover.new(*values)
+    end
+    alias_matcher :a_range_covering, :cover
+    alias_matcher :covering,         :cover
+
+    # Matches if the actual value ends with the expected value(s). In the case
+    # of a string, matches against the last `expected.length` characters of the
+    # actual string. In the case of an array, matches against the last
+    # `expected.length` elements of the actual array.
+    #
+    # @example
+    #   expect("this string").to   end_with "string"
+    #   expect([0, 1, 2, 3, 4]).to end_with 4
+    #   expect([0, 2, 3, 4, 4]).to end_with 3, 4
+    def end_with(*expected)
+      BuiltIn::EndWith.new(*expected)
+    end
+    alias_matcher :a_collection_ending_with, :end_with
+    alias_matcher :a_string_ending_with,     :end_with
+    alias_matcher :ending_with,              :end_with
+
+    # Passes if <tt>actual == expected</tt>.
+    #
+    # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
+    # information about equality in Ruby.
+    #
+    # @example
+    #   expect(5).to     eq(5)
+    #   expect(5).not_to eq(3)
+    def eq(expected)
+      BuiltIn::Eq.new(expected)
+    end
+    alias_matcher :an_object_eq_to, :eq
+    alias_matcher :eq_to,           :eq
+
+    # Passes if `actual.eql?(expected)`
+    #
+    # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
+    # information about equality in Ruby.
+    #
+    # @example
+    #   expect(5).to     eql(5)
+    #   expect(5).not_to eql(3)
+    def eql(expected)
+      BuiltIn::Eql.new(expected)
+    end
+    alias_matcher :an_object_eql_to, :eql
+    alias_matcher :eql_to,           :eql
+
+    # Passes if <tt>actual.equal?(expected)</tt> (object identity).
+    #
+    # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
+    # information about equality in Ruby.
+    #
+    # @example
+    #   expect(5).to       equal(5)   # Fixnums are equal
+    #   expect("5").not_to equal("5") # Strings that look the same are not the same object
+    def equal(expected)
+      BuiltIn::Equal.new(expected)
+    end
+    alias_matcher :an_object_equal_to, :equal
+    alias_matcher :equal_to,           :equal
+
+    # Passes if `actual.exist?` or `actual.exists?`
+    #
+    # @example
+    #   expect(File).to exist("path/to/file")
+    def exist(*args)
+      BuiltIn::Exist.new(*args)
+    end
+    alias_matcher :an_object_existing, :exist
+    alias_matcher :existing,           :exist
+
+    # Passes if actual's attribute values match the expected attributes hash.
+    # This works no matter how you define your attribute readers.
+    #
+    # @example
+    #   Person = Struct.new(:name, :age)
+    #   person = Person.new("Bob", 32)
+    #
+    #   expect(person).to have_attributes(:name => "Bob", :age => 32)
+    #   expect(person).to have_attributes(:name => a_string_starting_with("B"), :age => (a_value > 30) )
+    #
+    # @note It will fail if actual doesn't respond to any of the expected attributes.
+    #
+    # @example
+    #   expect(person).to have_attributes(:color => "red")
+    def have_attributes(expected)
+      BuiltIn::HaveAttributes.new(expected)
+    end
+    alias_matcher :an_object_having_attributes, :have_attributes
+
+    # Passes if actual includes expected. This works for
+    # collections and Strings. You can also pass in multiple args
+    # and it will only pass if all args are found in collection.
+    #
+    # @example
+    #   expect([1,2,3]).to      include(3)
+    #   expect([1,2,3]).to      include(2,3)
+    #   expect([1,2,3]).to      include(2,3,4) # fails
+    #   expect([1,2,3]).not_to  include(4)
+    #   expect("spread").to     include("read")
+    #   expect("spread").not_to include("red")
+    #   expect(:a => 1, :b => 2).to include(:a)
+    #   expect(:a => 1, :b => 2).to include(:a, :b)
+    #   expect(:a => 1, :b => 2).to include(:a => 1)
+    #   expect(:a => 1, :b => 2).to include(:b => 2, :a => 1)
+    #   expect(:a => 1, :b => 2).to include(:c) # fails
+    #   expect(:a => 1, :b => 2).not_to include(:a => 2)
+    def include(*expected)
+      BuiltIn::Include.new(*expected)
+    end
+    alias_matcher :a_collection_including, :include
+    alias_matcher :a_string_including,     :include
+    alias_matcher :a_hash_including,       :include
+    alias_matcher :including,              :include
+
+    # Passes if the provided matcher passes when checked against all
+    # elements of the collection.
+    #
+    # @example
+    #   expect([1, 3, 5]).to all be_odd
+    #   expect([1, 3, 6]).to all be_odd # fails
+    #
+    # @note The negative form `not_to all` is not supported. Instead
+    #   use `not_to include` or pass a negative form of a matcher
+    #   as the argument (e.g. `all exclude(:foo)`).
+    #
+    # @note You can also use this with compound matchers as well.
+    #
+    # @example
+    #   expect([1, 3, 5]).to all( be_odd.and be_an(Integer) )
+    def all(expected)
+      BuiltIn::All.new(expected)
+    end
+
+    # Given a `Regexp` or `String`, passes if `actual.match(pattern)`
+    # Given an arbitrary nested data structure (e.g. arrays and hashes),
+    # matches if `expected === actual` || `actual == expected` for each
+    # pair of elements.
+    #
+    # @example
+    #   expect(email).to match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
+    #   expect(email).to match("@example.com")
+    #
+    # @example
+    #   hash = {
+    #     :a => {
+    #       :b => ["foo", 5],
+    #       :c => { :d => 2.05 }
+    #     }
+    #   }
+    #
+    #   expect(hash).to match(
+    #     :a => {
+    #       :b => a_collection_containing_exactly(
+    #         a_string_starting_with("f"),
+    #         an_instance_of(Fixnum)
+    #       ),
+    #       :c => { :d => (a_value < 3) }
+    #     }
+    #   )
+    #
+    # @note The `match_regex` alias is deprecated and is not recommended for use.
+    #       It was added in 2.12.1 to facilitate its use from within custom
+    #       matchers (due to how the custom matcher DSL was evaluated in 2.x,
+    #       `match` could not be used there), but is no longer needed in 3.x.
+    def match(expected)
+      BuiltIn::Match.new(expected)
+    end
+    alias_matcher :match_regex,        :match
+    alias_matcher :an_object_matching, :match
+    alias_matcher :a_string_matching,  :match
+    alias_matcher :matching,           :match
+
+    # An alternate form of `contain_exactly` that accepts
+    # the expected contents as a single array arg rather
+    # that splatted out as individual items.
+    #
+    # @example
+    #   expect(results).to contain_exactly(1, 2)
+    #   # is identical to:
+    #   expect(results).to match_array([1, 2])
+    #
+    # @see #contain_exactly
+    def match_array(items)
+      contain_exactly(*items)
+    end
+
+    # With no arg, passes if the block outputs `to_stdout` or `to_stderr`.
+    # With a string, passes if the block outputs that specific string `to_stdout` or `to_stderr`.
+    # With a regexp or matcher, passes if the block outputs a string `to_stdout` or `to_stderr` that matches.
+    #
+    # To capture output from any spawned subprocess as well, use `to_stdout_from_any_process` or
+    # `to_stderr_from_any_process`. Output from any process that inherits the main process's corresponding
+    # standard stream will be captured.
+    #
+    # @example
+    #   expect { print 'foo' }.to output.to_stdout
+    #   expect { print 'foo' }.to output('foo').to_stdout
+    #   expect { print 'foo' }.to output(/foo/).to_stdout
+    #
+    #   expect { do_something }.to_not output.to_stdout
+    #
+    #   expect { warn('foo') }.to output.to_stderr
+    #   expect { warn('foo') }.to output('foo').to_stderr
+    #   expect { warn('foo') }.to output(/foo/).to_stderr
+    #
+    #   expect { do_something }.to_not output.to_stderr
+    #
+    #   expect { system('echo foo') }.to output("foo\n").to_stdout_from_any_process
+    #   expect { system('echo foo', out: :err) }.to output("foo\n").to_stderr_from_any_process
+    #
+    # @note `to_stdout` and `to_stderr` work by temporarily replacing `$stdout` or `$stderr`,
+    #   so they're not able to intercept stream output that explicitly uses `STDOUT`/`STDERR`
+    #   or that uses a reference to `$stdout`/`$stderr` that was stored before the
+    #   matcher was used.
+    # @note `to_stdout_from_any_process` and `to_stderr_from_any_process` use Tempfiles, and
+    #   are thus significantly (~30x) slower than `to_stdout` and `to_stderr`.
+    def output(expected=nil)
+      BuiltIn::Output.new(expected)
+    end
+    alias_matcher :a_block_outputting, :output
+
+    # With no args, matches if any error is raised.
+    # With a named error, matches only if that specific error is raised.
+    # With a named error and messsage specified as a String, matches only if both match.
+    # With a named error and messsage specified as a Regexp, matches only if both match.
+    # Pass an optional block to perform extra verifications on the exception matched
+    #
+    # @example
+    #   expect { do_something_risky }.to raise_error
+    #   expect { do_something_risky }.to raise_error(PoorRiskDecisionError)
+    #   expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 }
+    #   expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky")
+    #   expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/)
+    #
+    #   expect { do_something_risky }.not_to raise_error
+    def raise_error(error=Exception, message=nil, &block)
+      BuiltIn::RaiseError.new(error, message, &block)
+    end
+    alias_method :raise_exception,  :raise_error
+
+    alias_matcher :a_block_raising,  :raise_error do |desc|
+      desc.sub("raise", "a block raising")
+    end
+
+    alias_matcher :raising,        :raise_error do |desc|
+      desc.sub("raise", "raising")
+    end
+
+    # Matches if the target object responds to all of the names
+    # provided. Names can be Strings or Symbols.
+    #
+    # @example
+    #   expect("string").to respond_to(:length)
+    #
+    def respond_to(*names)
+      BuiltIn::RespondTo.new(*names)
+    end
+    alias_matcher :an_object_responding_to, :respond_to
+    alias_matcher :responding_to,           :respond_to
+
+    # Passes if the submitted block returns true. Yields target to the
+    # block.
+    #
+    # Generally speaking, this should be thought of as a last resort when
+    # you can't find any other way to specify the behaviour you wish to
+    # specify.
+    #
+    # If you do find yourself in such a situation, you could always write
+    # a custom matcher, which would likely make your specs more expressive.
+    #
+    # @example
+    #   expect(5).to satisfy { |n| n > 3 }
+    def satisfy(&block)
+      BuiltIn::Satisfy.new(&block)
+    end
+    alias_matcher :an_object_satisfying, :satisfy
+    alias_matcher :satisfying,           :satisfy
+
+    # Matches if the actual value starts with the expected value(s). In the
+    # case of a string, matches against the first `expected.length` characters
+    # of the actual string. In the case of an array, matches against the first
+    # `expected.length` elements of the actual array.
+    #
+    # @example
+    #   expect("this string").to   start_with "this s"
+    #   expect([0, 1, 2, 3, 4]).to start_with 0
+    #   expect([0, 2, 3, 4, 4]).to start_with 0, 1
+    def start_with(*expected)
+      BuiltIn::StartWith.new(*expected)
+    end
+    alias_matcher :a_collection_starting_with, :start_with
+    alias_matcher :a_string_starting_with,     :start_with
+    alias_matcher :starting_with,              :start_with
+
+    # Given no argument, matches if a proc throws any Symbol.
+    #
+    # Given a Symbol, matches if the given proc throws the specified Symbol.
+    #
+    # Given a Symbol and an arg, matches if the given proc throws the
+    # specified Symbol with the specified arg.
+    #
+    # @example
+    #   expect { do_something_risky }.to throw_symbol
+    #   expect { do_something_risky }.to throw_symbol(:that_was_risky)
+    #   expect { do_something_risky }.to throw_symbol(:that_was_risky, 'culprit')
+    #
+    #   expect { do_something_risky }.not_to throw_symbol
+    #   expect { do_something_risky }.not_to throw_symbol(:that_was_risky)
+    #   expect { do_something_risky }.not_to throw_symbol(:that_was_risky, 'culprit')
+    def throw_symbol(expected_symbol=nil, expected_arg=nil)
+      BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg)
+    end
+
+    alias_matcher :a_block_throwing, :throw_symbol do |desc|
+      desc.sub("throw", "a block throwing")
+    end
+
+    alias_matcher :throwing,        :throw_symbol do |desc|
+      desc.sub("throw", "throwing")
+    end
+
+    # Passes if the method called in the expect block yields, regardless
+    # of whether or not arguments are yielded.
+    #
+    # @example
+    #   expect { |b| 5.tap(&b) }.to yield_control
+    #   expect { |b| "a".to_sym(&b) }.not_to yield_control
+    #
+    # @note Your expect block must accept a parameter and pass it on to
+    #   the method-under-test as a block.
+    def yield_control
+      BuiltIn::YieldControl.new
+    end
+    alias_matcher :a_block_yielding_control,  :yield_control
+    alias_matcher :yielding_control,          :yield_control
+
+    # Passes if the method called in the expect block yields with
+    # no arguments. Fails if it does not yield, or yields with arguments.
+    #
+    # @example
+    #   expect { |b| User.transaction(&b) }.to yield_with_no_args
+    #   expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5`
+    #   expect { |b| "a".to_sym(&b) }.not_to yield_with_no_args # because it does not yield
+    #
+    # @note Your expect block must accept a parameter and pass it on to
+    #   the method-under-test as a block.
+    # @note This matcher is not designed for use with methods that yield
+    #   multiple times.
+    def yield_with_no_args
+      BuiltIn::YieldWithNoArgs.new
+    end
+    alias_matcher :a_block_yielding_with_no_args,  :yield_with_no_args
+    alias_matcher :yielding_with_no_args,          :yield_with_no_args
+
+    # Given no arguments, matches if the method called in the expect
+    # block yields with arguments (regardless of what they are or how
+    # many there are).
+    #
+    # Given arguments, matches if the method called in the expect block
+    # yields with arguments that match the given arguments.
+    #
+    # Argument matching is done using `===` (the case match operator)
+    # and `==`. If the expected and actual arguments match with either
+    # operator, the matcher will pass.
+    #
+    # @example
+    #   expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg
+    #   expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5
+    #   expect { |b| 5.tap(&b) }.to yield_with_args(Fixnum) # because Fixnum === 5
+    #   expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt"
+    #
+    #   expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args
+    #   expect { |b| 5.tap(&b) }.not_to yield_with_args(1, 2, 3)
+    #
+    # @note Your expect block must accept a parameter and pass it on to
+    #   the method-under-test as a block.
+    # @note This matcher is not designed for use with methods that yield
+    #   multiple times.
+    def yield_with_args(*args)
+      BuiltIn::YieldWithArgs.new(*args)
+    end
+    alias_matcher :a_block_yielding_with_args,  :yield_with_args
+    alias_matcher :yielding_with_args,          :yield_with_args
+
+    # Designed for use with methods that repeatedly yield (such as
+    # iterators). Passes if the method called in the expect block yields
+    # multiple times with arguments matching those given.
+    #
+    # Argument matching is done using `===` (the case match operator)
+    # and `==`. If the expected and actual arguments match with either
+    # operator, the matcher will pass.
+    #
+    # @example
+    #   expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
+    #   expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
+    #   expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2)
+    #
+    # @note Your expect block must accept a parameter and pass it on to
+    #   the method-under-test as a block.
+    def yield_successive_args(*args)
+      BuiltIn::YieldSuccessiveArgs.new(*args)
+    end
+    alias_matcher :a_block_yielding_successive_args,  :yield_successive_args
+    alias_matcher :yielding_successive_args,          :yield_successive_args
+
+    # Delegates to {RSpec::Expectations.configuration}.
+    # This is here because rspec-core's `expect_with` option
+    # looks for a `configuration` method on the mixin
+    # (`RSpec::Matchers`) to yield to a block.
+    # @return [RSpec::Expectations::Configuration] the configuration object
+    def self.configuration
+      Expectations.configuration
+    end
+
+  private
+
+    BE_PREDICATE_REGEX = /^(be_(?:an?_)?)(.*)/
+    HAS_REGEX = /^(?:have_)(.*)/
+
+    def method_missing(method, *args, &block)
+      case method.to_s
+      when BE_PREDICATE_REGEX
+        BuiltIn::BePredicate.new(method, *args, &block)
+      when HAS_REGEX
+        BuiltIn::Has.new(method, *args, &block)
+      else
+        super
+      end
+    end
+
+    # @api private
+    def self.is_a_matcher?(obj)
+      return true  if ::RSpec::Matchers::BuiltIn::BaseMatcher === obj
+      begin
+        return false if obj.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher)
+      rescue NoMethodError
+        # Some objects, like BasicObject, don't implemented standard
+        # reflection methods.
+        return false
+      end
+      return false unless obj.respond_to?(:matches?)
+
+      obj.respond_to?(:failure_message) ||
+      obj.respond_to?(:failure_message_for_should) # support legacy matchers
+    end
+
+    ::RSpec::Support.register_matcher_definition do |obj|
+      is_a_matcher?(obj)
+    end
+
+    # @api private
+    def self.is_a_describable_matcher?(obj)
+      is_a_matcher?(obj) && obj.respond_to?(:description)
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/aliased_matcher.rb b/rspec-expectations/lib/rspec/matchers/aliased_matcher.rb
new file mode 100644
index 0000000..c384d2a
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/aliased_matcher.rb
@@ -0,0 +1,116 @@
+module RSpec
+  module Matchers
+    # Decorator that wraps a matcher and overrides `description`
+    # using the provided block in order to support an alias
+    # of a matcher. This is intended for use when composing
+    # matchers, so that you can use an expression like
+    # `include( a_value_within(0.1).of(3) )` rather than
+    # `include( be_within(0.1).of(3) )`, and have the corresponding
+    # description read naturally.
+    #
+    # @api private
+    class AliasedMatcher < MatcherDelegator
+      def initialize(base_matcher, description_block)
+        @description_block = description_block
+        super(base_matcher)
+      end
+
+      # Forward messages on to the wrapped matcher.
+      # Since many matchers provide a fluent interface
+      # (e.g. `a_value_within(0.1).of(3)`), we need to wrap
+      # the returned value if it responds to `description`,
+      # so that our override can be applied when it is eventually
+      # used.
+      def method_missing(*)
+        return_val = super
+        return return_val unless RSpec::Matchers.is_a_matcher?(return_val)
+        self.class.new(return_val, @description_block)
+      end
+
+      # Provides the description of the aliased matcher. Aliased matchers
+      # are designed to behave identically to the original matcher except
+      # for the description and failure messages. The description is different
+      # to reflect the aliased name.
+      #
+      # @api private
+      def description
+        @description_block.call(super)
+      end
+
+      # Provides the failure_message of the aliased matcher. Aliased matchers
+      # are designed to behave identically to the original matcher except
+      # for the description and failure messages. The failure_message is different
+      # to reflect the aliased name.
+      #
+      # @api private
+      def failure_message
+        @description_block.call(super)
+      end
+
+      # Provides the failure_message_when_negated of the aliased matcher. Aliased matchers
+      # are designed to behave identically to the original matcher except
+      # for the description and failure messages. The failure_message_when_negated is different
+      # to reflect the aliased name.
+      #
+      # @api private
+      def failure_message_when_negated
+        @description_block.call(super)
+      end
+    end
+
+    # Decorator used for matchers that have special implementations of
+    # operators like `==` and `===`.
+    # @private
+    class AliasedMatcherWithOperatorSupport < AliasedMatcher
+      # We undef these so that they get delegated via `method_missing`.
+      undef ==
+      undef ===
+    end
+
+    # @private
+    class AliasedNegatedMatcher < AliasedMatcher
+      def matches?(*args, &block)
+        if @base_matcher.respond_to?(:does_not_match?)
+          @base_matcher.does_not_match?(*args, &block)
+        else
+          !super
+        end
+      end
+
+      def does_not_match?(*args, &block)
+        @base_matcher.matches?(*args, &block)
+      end
+
+      def failure_message
+        optimal_failure_message(__method__, :failure_message_when_negated)
+      end
+
+      def failure_message_when_negated
+        optimal_failure_message(__method__, :failure_message)
+      end
+
+    private
+
+      DefaultFailureMessages = BuiltIn::BaseMatcher::DefaultFailureMessages
+
+      # For a matcher that uses the default failure messages, we prefer to
+      # use the override provided by the `description_block`, because it
+      # includes the phrasing that the user has expressed a preference for
+      # by going through the effort of defining a negated matcher.
+      #
+      # However, if the override didn't actually change anything, then we
+      # should return the opposite failure message instead -- the overriden
+      # message is going to be confusing if we return it as-is, as it represents
+      # the non-negated failure message for a negated match (or vice versa).
+      def optimal_failure_message(same, inverted)
+        if DefaultFailureMessages.has_default_failure_messages?(@base_matcher)
+          base_message = @base_matcher.__send__(same)
+          overriden    = @description_block.call(base_message)
+          return overriden if overriden != base_message
+        end
+
+        @base_matcher.__send__(inverted)
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in.rb b/rspec-expectations/lib/rspec/matchers/built_in.rb
new file mode 100644
index 0000000..7f184a0
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in.rb
@@ -0,0 +1,52 @@
+RSpec::Support.require_rspec_matchers "built_in/base_matcher"
+
+module RSpec
+  module Matchers
+    # Container module for all built-in matchers. The matcher classes are here
+    # (rather than directly under `RSpec::Matchers`) in order to prevent name
+    # collisions, since `RSpec::Matchers` gets included into the user's namespace.
+    #
+    # Autoloading is used to delay when the matcher classes get loaded, allowing
+    # rspec-matchers to boot faster, and avoiding loading matchers the user is
+    # not using.
+    module BuiltIn
+      autoload :BeAKindOf,               'rspec/matchers/built_in/be_kind_of'
+      autoload :BeAnInstanceOf,          'rspec/matchers/built_in/be_instance_of'
+      autoload :BeBetween,               'rspec/matchers/built_in/be_between'
+      autoload :Be,                      'rspec/matchers/built_in/be'
+      autoload :BeComparedTo,            'rspec/matchers/built_in/be'
+      autoload :BeFalsey,                'rspec/matchers/built_in/be'
+      autoload :BeNil,                   'rspec/matchers/built_in/be'
+      autoload :BePredicate,             'rspec/matchers/built_in/be'
+      autoload :BeTruthy,                'rspec/matchers/built_in/be'
+      autoload :BeWithin,                'rspec/matchers/built_in/be_within'
+      autoload :Change,                  'rspec/matchers/built_in/change'
+      autoload :Compound,                'rspec/matchers/built_in/compound'
+      autoload :ContainExactly,          'rspec/matchers/built_in/contain_exactly'
+      autoload :Cover,                   'rspec/matchers/built_in/cover'
+      autoload :EndWith,                 'rspec/matchers/built_in/start_or_end_with'
+      autoload :Eq,                      'rspec/matchers/built_in/eq'
+      autoload :Eql,                     'rspec/matchers/built_in/eql'
+      autoload :Equal,                   'rspec/matchers/built_in/equal'
+      autoload :Exist,                   'rspec/matchers/built_in/exist'
+      autoload :Has,                     'rspec/matchers/built_in/has'
+      autoload :HaveAttributes,          'rspec/matchers/built_in/have_attributes'
+      autoload :Include,                 'rspec/matchers/built_in/include'
+      autoload :All,                     'rspec/matchers/built_in/all'
+      autoload :Match,                   'rspec/matchers/built_in/match'
+      autoload :NegativeOperatorMatcher, 'rspec/matchers/built_in/operators'
+      autoload :OperatorMatcher,         'rspec/matchers/built_in/operators'
+      autoload :Output,                  'rspec/matchers/built_in/output'
+      autoload :PositiveOperatorMatcher, 'rspec/matchers/built_in/operators'
+      autoload :RaiseError,              'rspec/matchers/built_in/raise_error'
+      autoload :RespondTo,               'rspec/matchers/built_in/respond_to'
+      autoload :Satisfy,                 'rspec/matchers/built_in/satisfy'
+      autoload :StartWith,               'rspec/matchers/built_in/start_or_end_with'
+      autoload :ThrowSymbol,             'rspec/matchers/built_in/throw_symbol'
+      autoload :YieldControl,            'rspec/matchers/built_in/yield'
+      autoload :YieldSuccessiveArgs,     'rspec/matchers/built_in/yield'
+      autoload :YieldWithArgs,           'rspec/matchers/built_in/yield'
+      autoload :YieldWithNoArgs,         'rspec/matchers/built_in/yield'
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/all.rb b/rspec-expectations/lib/rspec/matchers/built_in/all.rb
new file mode 100644
index 0000000..0d8e360
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/all.rb
@@ -0,0 +1,85 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `all`.
+      # Not intended to be instantiated directly.
+      class All < BaseMatcher
+        # @private
+        attr_reader :matcher, :failed_objects
+
+        def initialize(matcher)
+          @matcher = matcher
+          @failed_objects = {}
+        end
+
+        # @private
+        def does_not_match?(_actual)
+          raise NotImplementedError, '`expect().not_to all( matcher )` is not supported.'
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          unless iterable?
+            return "#{improve_hash_formatting(super)}, but was not iterable"
+          end
+
+          all_messages = [improve_hash_formatting(super)]
+          failed_objects.each do |index, matcher_failure_message|
+            all_messages << failure_message_for_item(index, matcher_failure_message)
+          end
+          all_messages.join("\n\n")
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          improve_hash_formatting "all #{description_of matcher}"
+        end
+
+      private
+
+        def match(_expected, _actual)
+          return false unless iterable?
+
+          index_failed_objects
+          failed_objects.empty?
+        end
+
+        def index_failed_objects
+          actual.each_with_index do |actual_item, index|
+            cloned_matcher = matcher.clone
+            matches = cloned_matcher.matches?(actual_item)
+            failed_objects[index] = cloned_matcher.failure_message unless matches
+          end
+        end
+
+        def failure_message_for_item(index, failure_message)
+          failure_message = indent_multiline_message(add_new_line_if_needed(failure_message))
+          indent_multiline_message("object at index #{index} failed to match:#{failure_message}")
+        end
+
+        def add_new_line_if_needed(message)
+          message.start_with?("\n") ? message : "\n#{message}"
+        end
+
+        def indent_multiline_message(message)
+          message = message.sub(/\n+\z/, '')
+          message.lines.map do |line|
+            line =~ /\S/ ? '   ' + line : line
+          end.join
+        end
+
+        def initialize_copy(other)
+          @matcher = @matcher.clone
+          super
+        end
+
+        def iterable?
+          @actual.respond_to?(:each_with_index)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/base_matcher.rb b/rspec-expectations/lib/rspec/matchers/built_in/base_matcher.rb
new file mode 100644
index 0000000..0143a8a
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/base_matcher.rb
@@ -0,0 +1,132 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      #
+      # Used _internally_ as a base class for matchers that ship with
+      # rspec-expectations and rspec-rails.
+      #
+      # ### Warning:
+      #
+      # This class is for internal use, and subject to change without notice.  We
+      # strongly recommend that you do not base your custom matchers on this
+      # class. If/when this changes, we will announce it and remove this warning.
+      class BaseMatcher
+        include RSpec::Matchers::Pretty
+        include RSpec::Matchers::Composable
+
+        # @api private
+        # Used to detect when no arg is passed to `initialize`.
+        # `nil` cannot be used because it's a valid value to pass.
+        UNDEFINED = Object.new.freeze
+
+        # @private
+        attr_reader :actual, :expected, :rescued_exception
+
+        def initialize(expected=UNDEFINED)
+          @expected = expected unless UNDEFINED.equal?(expected)
+        end
+
+        # @api private
+        # Indicates if the match is successful. Delegates to `match`, which
+        # should be defined on a subclass. Takes care of consistently
+        # initializing the `actual` attribute.
+        def matches?(actual)
+          @actual = actual
+          match(expected, actual)
+        end
+
+        # @api private
+        # Used to wrap a block of code that will indicate failure by
+        # raising one of the named exceptions.
+        #
+        # This is used by rspec-rails for some of its matchers that
+        # wrap rails' assertions.
+        def match_unless_raises(*exceptions)
+          exceptions.unshift Exception if exceptions.empty?
+          begin
+            yield
+            true
+          rescue *exceptions => @rescued_exception
+            false
+          end
+        end
+
+        # @api private
+        # Generates a "pretty" description using the logic in {Pretty}.
+        # @return [String]
+        def description
+          return name_to_sentence unless defined?(@expected)
+          "#{name_to_sentence}#{to_sentence @expected}"
+        end
+
+        # @api private
+        # Matchers are not diffable by default. Override this to make your
+        # subclass diffable.
+        def diffable?
+          false
+        end
+
+        # @api private
+        # Most matchers are value matchers (i.e. meant to work with `expect(value)`)
+        # rather than block matchers (i.e. meant to work with `expect { }`), so
+        # this defaults to false. Block matchers must override this to return true.
+        def supports_block_expectations?
+          false
+        end
+
+        # @api private
+        def expects_call_stack_jump?
+          false
+        end
+
+      private
+
+        def assert_ivars(*expected_ivars)
+          return unless (expected_ivars - present_ivars).any?
+          raise "#{self.class.name} needs to supply#{to_sentence expected_ivars}"
+        end
+
+        if RUBY_VERSION.to_f < 1.9
+          def present_ivars
+            instance_variables.map { |v| v.to_sym }
+          end
+        else
+          alias present_ivars instance_variables
+        end
+
+        # @api private
+        # Provides default implementations of failure messages, based on the `description`.
+        module DefaultFailureMessages
+          # @api private
+          # Provides a good generic failure message. Based on `description`.
+          # When subclassing, if you are not satisfied with this failure message
+          # you often only need to override `description`.
+          # @return [String]
+          def failure_message
+            "expected #{actual.inspect} to #{description}"
+          end
+
+          # @api private
+          # Provides a good generic negative failure message. Based on `description`.
+          # When subclassing, if you are not satisfied with this failure message
+          # you often only need to override `description`.
+          # @return [String]
+          def failure_message_when_negated
+            "expected #{actual.inspect} not to #{description}"
+          end
+
+          # @private
+          def self.has_default_failure_messages?(matcher)
+            matcher.method(:failure_message).owner == self &&
+            matcher.method(:failure_message_when_negated).owner == self
+          rescue NameError
+            false
+          end
+        end
+
+        include DefaultFailureMessages
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/be.rb b/rspec-expectations/lib/rspec/matchers/built_in/be.rb
new file mode 100644
index 0000000..aefd743
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/be.rb
@@ -0,0 +1,273 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `be_truthy`.
+      # Not intended to be instantiated directly.
+      class BeTruthy < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected: truthy value\n     got: #{actual.inspect}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected: falsey value\n     got: #{actual.inspect}"
+        end
+
+      private
+
+        def match(_, actual)
+          !!actual
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `be_falsey`.
+      # Not intended to be instantiated directly.
+      class BeFalsey < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected: falsey value\n     got: #{actual.inspect}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected: truthy value\n     got: #{actual.inspect}"
+        end
+
+      private
+
+        def match(_, actual)
+          !actual
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `be_nil`.
+      # Not intended to be instantiated directly.
+      class BeNil < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected: nil\n     got: #{actual.inspect}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected: not nil\n     got: nil"
+        end
+
+      private
+
+        def match(_, actual)
+          actual.nil?
+        end
+      end
+
+      # @private
+      module BeHelpers
+      private
+
+        def args_to_s
+          @args.empty? ? "" : parenthesize(inspected_args.join(', '))
+        end
+
+        def parenthesize(string)
+          "(#{string})"
+        end
+
+        def inspected_args
+          @args.map { |a| a.inspect }
+        end
+
+        def expected_to_sentence
+          split_words(@expected)
+        end
+
+        def args_to_sentence
+          to_sentence(@args)
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `be`.
+      # Not intended to be instantiated directly.
+      class Be < BaseMatcher
+        include BeHelpers
+
+        def initialize(*args)
+          @args = args
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{@actual.inspect} to evaluate to true"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{@actual.inspect} to evaluate to false"
+        end
+
+        [:==, :<, :<=, :>=, :>, :===, :=~].each do |operator|
+          define_method operator do |operand|
+            BeComparedTo.new(operand, operator)
+          end
+        end
+
+      private
+
+        def match(_, actual)
+          !!actual
+        end
+      end
+
+      # @api private
+      # Provides the implementation of `be <operator> value`.
+      # Not intended to be instantiated directly.
+      class BeComparedTo < BaseMatcher
+        include BeHelpers
+
+        def initialize(operand, operator)
+          @expected, @operator = operand, operator
+          @args = []
+        end
+
+        def matches?(actual)
+          @actual = actual
+          @actual.__send__ @operator, @expected
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected: #{@operator} #{@expected.inspect}\n     got: #{@operator.to_s.gsub(/./, ' ')} #{@actual.inspect}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          message = "`expect(#{@actual.inspect}).not_to be #{@operator} #{@expected.inspect}`"
+          if [:<, :>, :<=, :>=].include?(@operator)
+            message + " not only FAILED, it is a bit confusing."
+          else
+            message
+          end
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
+        end
+      end
+
+      # @api private
+      # Provides the implementation of `be_<predicate>`.
+      # Not intended to be instantiated directly.
+      class BePredicate < BaseMatcher
+        include BeHelpers
+
+        def initialize(*args, &block)
+          @expected = parse_expected(args.shift)
+          @args = args
+          @block = block
+        end
+
+        def matches?(actual, &block)
+          @actual  = actual
+          @block ||= block
+          predicate_accessible? && predicate_matches?
+        end
+
+        def does_not_match?(actual, &block)
+          @actual  = actual
+          @block ||= block
+          predicate_accessible? && !predicate_matches?
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          failure_message_expecting(true)
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          failure_message_expecting(false)
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "#{prefix_to_sentence}#{expected_to_sentence}#{args_to_sentence}"
+        end
+
+      private
+
+        def predicate_accessible?
+          actual.respond_to?(predicate) || actual.respond_to?(present_tense_predicate)
+        end
+
+        # support 1.8.7, evaluate once at load time for performance
+        if String === methods.first
+          def private_predicate?
+            @actual.private_methods.include? predicate.to_s
+          end
+        else
+          def private_predicate?
+            @actual.private_methods.include? predicate
+          end
+        end
+
+        def predicate_matches?
+          method_name = actual.respond_to?(predicate) ? predicate : present_tense_predicate
+          @predicate_matches = actual.__send__(method_name, *@args, &@block)
+        end
+
+        def predicate
+          :"#{@expected}?"
+        end
+
+        def present_tense_predicate
+          :"#{@expected}s?"
+        end
+
+        def parse_expected(expected)
+          @prefix, expected = prefix_and_expected(expected)
+          expected
+        end
+
+        def prefix_and_expected(symbol)
+          Matchers::BE_PREDICATE_REGEX.match(symbol.to_s).captures.compact
+        end
+
+        def prefix_to_sentence
+          split_words(@prefix)
+        end
+
+        def failure_message_expecting(value)
+          validity_message ||
+            "expected `#{@actual.inspect}.#{predicate}#{args_to_s}` to return #{value}, got #{@predicate_matches.inspect}"
+        end
+
+        def validity_message
+          return nil if predicate_accessible?
+
+          msg = "expected #{@actual} to respond to `#{predicate}`"
+          msg << " but `#{predicate}` is a private method" if private_predicate?
+          msg
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/be_between.rb b/rspec-expectations/lib/rspec/matchers/built_in/be_between.rb
new file mode 100644
index 0000000..58c6219
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/be_between.rb
@@ -0,0 +1,77 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `be_between`.
+      # Not intended to be instantiated directly.
+      class BeBetween < BaseMatcher
+        def initialize(min, max)
+          @min, @max = min, max
+          inclusive
+        end
+
+        # @api public
+        # Makes the between comparison inclusive.
+        #
+        # @example
+        #   expect(3).to be_between(2, 3).inclusive
+        #
+        # @note The matcher is inclusive by default; this simply provides
+        #       a way to be more explicit about it.
+        def inclusive
+          @less_than_operator = :<=
+          @greater_than_operator = :>=
+          @mode = :inclusive
+          self
+        end
+
+        # @api public
+        # Makes the between comparison exclusive.
+        #
+        # @example
+        #   expect(3).to be_between(2, 4).exclusive
+        def exclusive
+          @less_than_operator = :<
+          @greater_than_operator = :>
+          @mode = :exclusive
+          self
+        end
+
+        # @api private
+        # @return [Boolean]
+        def matches?(actual)
+          @actual = actual
+          comparable? && compare
+        rescue ArgumentError
+          false
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "#{super}#{not_comparable_clause}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "be between #{@min.inspect} and #{@max.inspect} (#{@mode})"
+        end
+
+      private
+
+        def comparable?
+          @actual.respond_to?(@less_than_operator) && @actual.respond_to?(@greater_than_operator)
+        end
+
+        def not_comparable_clause
+          ", but it does not respond to `#{@less_than_operator}` and `#{@greater_than_operator}`" unless comparable?
+        end
+
+        def compare
+          @actual.__send__(@greater_than_operator, @min) && @actual.__send__(@less_than_operator, @max)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/be_instance_of.rb b/rspec-expectations/lib/rspec/matchers/built_in/be_instance_of.rb
new file mode 100644
index 0000000..c6968f1
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/be_instance_of.rb
@@ -0,0 +1,22 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `be_an_instance_of`.
+      # Not intended to be instantiated directly.
+      class BeAnInstanceOf < BaseMatcher
+        # @api private
+        # @return [String]
+        def description
+          "be an instance of #{expected}"
+        end
+
+      private
+
+        def match(expected, actual)
+          actual.instance_of? expected
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/be_kind_of.rb b/rspec-expectations/lib/rspec/matchers/built_in/be_kind_of.rb
new file mode 100644
index 0000000..eae9b26
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/be_kind_of.rb
@@ -0,0 +1,16 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `be_a_kind_of`.
+      # Not intended to be instantiated directly.
+      class BeAKindOf < BaseMatcher
+      private
+
+        def match(expected, actual)
+          actual.kind_of? expected
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/be_within.rb b/rspec-expectations/lib/rspec/matchers/built_in/be_within.rb
new file mode 100644
index 0000000..9f225a0
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/be_within.rb
@@ -0,0 +1,72 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `be_within`.
+      # Not intended to be instantiated directly.
+      class BeWithin < BaseMatcher
+        def initialize(delta)
+          @delta = delta
+        end
+
+        # @api public
+        # Sets the expected value.
+        def of(expected)
+          @expected  = expected
+          @tolerance = @delta
+          @unit      = ''
+          self
+        end
+
+        # @api public
+        # Sets the expected value, and makes the matcher do
+        # a percent comparison.
+        def percent_of(expected)
+          @expected  = expected
+          @tolerance = @delta * @expected.abs / 100.0
+          @unit      = '%'
+          self
+        end
+
+        # @private
+        def matches?(actual)
+          @actual = actual
+          raise needs_expected unless defined? @expected
+          numeric? && (@actual - @expected).abs <= @tolerance
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{@actual.inspect} to #{description}#{not_numeric_clause}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{@actual.inspect} not to #{description}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "be within #{@delta}#{@unit} of #{@expected}"
+        end
+
+      private
+
+        def numeric?
+          @actual.respond_to?(:-)
+        end
+
+        def needs_expected
+          ArgumentError.new "You must set an expected value using #of: be_within(#{@delta}).of(expected_value)"
+        end
+
+        def not_numeric_clause
+          ", but it could not be treated as a numeric value" unless numeric?
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/change.rb b/rspec-expectations/lib/rspec/matchers/built_in/change.rb
new file mode 100644
index 0000000..7fff8a5
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/change.rb
@@ -0,0 +1,337 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `change`.
+      # Not intended to be instantiated directly.
+      class Change < BaseMatcher
+        # @api public
+        # Specifies the delta of the expected change.
+        def by(expected_delta)
+          ChangeRelatively.new(@change_details, expected_delta, :by) do |actual_delta|
+            values_match?(expected_delta, actual_delta)
+          end
+        end
+
+        # @api public
+        # Specifies a minimum delta of the expected change.
+        def by_at_least(minimum)
+          ChangeRelatively.new(@change_details, minimum, :by_at_least) do |actual_delta|
+            actual_delta >= minimum
+          end
+        end
+
+        # @api public
+        # Specifies a maximum delta of the expected change.
+        def by_at_most(maximum)
+          ChangeRelatively.new(@change_details, maximum, :by_at_most) do |actual_delta|
+            actual_delta <= maximum
+          end
+        end
+
+        # @api public
+        # Specifies the new value you expect.
+        def to(value)
+          ChangeToValue.new(@change_details, value)
+        end
+
+        # @api public
+        # Specifies the original value.
+        def from(value)
+          ChangeFromValue.new(@change_details, value)
+        end
+
+        # @private
+        def matches?(event_proc)
+          @event_proc = event_proc
+          return false unless Proc === event_proc
+          raise_block_syntax_error if block_given?
+          @change_details.perform_change(event_proc)
+          @change_details.changed?
+        end
+
+        def does_not_match?(event_proc)
+          raise_block_syntax_error if block_given?
+          !matches?(event_proc) && Proc === event_proc
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{@change_details.message} to have changed, but #{positive_failure_reason}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{@change_details.message} not to have changed, but #{negative_failure_reason}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "change #{@change_details.message}"
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def initialize(receiver=nil, message=nil, &block)
+          @change_details = ChangeDetails.new(receiver, message, &block)
+        end
+
+        def raise_block_syntax_error
+          raise SyntaxError, "The block passed to the `change` matcher must " \
+            "use `{ ... }` instead of do/end"
+        end
+
+        def positive_failure_reason
+          return "was not given a block" unless Proc === @event_proc
+          "is still #{description_of @change_details.actual_before}"
+        end
+
+        def negative_failure_reason
+          return "was not given a block" unless Proc === @event_proc
+          "did change from #{description_of @change_details.actual_before} to #{description_of @change_details.actual_after}"
+        end
+      end
+
+      # Used to specify a relative change.
+      # @api private
+      class ChangeRelatively < BaseMatcher
+        def initialize(change_details, expected_delta, relativity, &comparer)
+          @change_details = change_details
+          @expected_delta = expected_delta
+          @relativity     = relativity
+          @comparer       = comparer
+        end
+
+        # @private
+        def failure_message
+          "expected #{@change_details.message} to have changed #{@relativity.to_s.gsub("_", " ")} #{description_of @expected_delta}, but #{failure_reason}"
+        end
+
+        # @private
+        def matches?(event_proc)
+          @event_proc = event_proc
+          return false unless Proc === event_proc
+          @change_details.perform_change(event_proc)
+          @comparer.call(@change_details.actual_delta)
+        end
+
+        # @private
+        def does_not_match?(_event_proc)
+          raise NotImplementedError, "`expect { }.not_to change { }.#{@relativity}()` is not supported"
+        end
+
+        # @private
+        def description
+          "change #{@change_details.message} #{@relativity.to_s.gsub("_", " ")} #{description_of @expected_delta}"
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def failure_reason
+          return "was not given a block" unless Proc === @event_proc
+          "was changed by #{description_of @change_details.actual_delta}"
+        end
+      end
+
+      # @api private
+      # Base class for specifying a change from and/or to specific values.
+      class SpecificValuesChange < BaseMatcher
+        # @private
+        MATCH_ANYTHING = ::Object.ancestors.last
+
+        def initialize(change_details, from, to)
+          @change_details  = change_details
+          @expected_before = from
+          @expected_after  = to
+        end
+
+        # @private
+        def matches?(event_proc)
+          @event_proc = event_proc
+          return false unless Proc === event_proc
+          @change_details.perform_change(event_proc)
+          @change_details.changed? && matches_before? && matches_after?
+        end
+
+        # @private
+        def description
+          "change #{@change_details.message} #{change_description}"
+        end
+
+        # @private
+        def failure_message
+          return not_given_a_block_failure unless Proc === @event_proc
+          return before_value_failure      unless matches_before?
+          return did_not_change_failure    unless @change_details.changed?
+          after_value_failure
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def matches_before?
+          values_match?(@expected_before, @change_details.actual_before)
+        end
+
+        def matches_after?
+          values_match?(@expected_after, @change_details.actual_after)
+        end
+
+        def before_value_failure
+          "expected #{@change_details.message} to have initially been #{description_of @expected_before}, but was #{description_of @change_details.actual_before}"
+        end
+
+        def after_value_failure
+          "expected #{@change_details.message} to have changed to #{description_of @expected_after}, but is now #{description_of @change_details.actual_after}"
+        end
+
+        def did_not_change_failure
+          "expected #{@change_details.message} to have changed #{change_description}, but did not change"
+        end
+
+        def did_change_failure
+          "expected #{@change_details.message} not to have changed, but did change from #{description_of @change_details.actual_before} to #{description_of @change_details.actual_after}"
+        end
+
+        def not_given_a_block_failure
+          "expected #{@change_details.message} to have changed #{change_description}, but was not given a block"
+        end
+      end
+
+      # @api private
+      # Used to specify a change from a specific value
+      # (and, optionally, to a specific value).
+      class ChangeFromValue < SpecificValuesChange
+        def initialize(change_details, expected_before)
+          @description_suffix = nil
+          super(change_details, expected_before, MATCH_ANYTHING)
+        end
+
+        # @api public
+        # Specifies the new value you expect.
+        def to(value)
+          @expected_after     = value
+          @description_suffix = " to #{description_of value}"
+          self
+        end
+
+        # @private
+        def does_not_match?(event_proc)
+          if @description_suffix
+            raise NotImplementedError, "`expect { }.not_to change { }.to()` is not supported"
+          end
+
+          @event_proc = event_proc
+          return false unless Proc === event_proc
+          @change_details.perform_change(event_proc)
+          !@change_details.changed? && matches_before?
+        end
+
+        # @private
+        def failure_message_when_negated
+          return not_given_a_block_failure unless Proc === @event_proc
+          return before_value_failure unless matches_before?
+          did_change_failure
+        end
+
+      private
+
+        def change_description
+          "from #{description_of @expected_before}#{@description_suffix}"
+        end
+      end
+
+      # @api private
+      # Used to specify a change to a specific value
+      # (and, optionally, from a specific value).
+      class ChangeToValue < SpecificValuesChange
+        def initialize(change_details, expected_after)
+          @description_suffix = nil
+          super(change_details, MATCH_ANYTHING, expected_after)
+        end
+
+        # @api public
+        # Specifies the original value.
+        def from(value)
+          @expected_before    = value
+          @description_suffix = " from #{description_of value}"
+          self
+        end
+
+        # @private
+        def does_not_match?(_event_proc)
+          raise NotImplementedError, "`expect { }.not_to change { }.to()` is not supported"
+        end
+
+      private
+
+        def change_description
+          "to #{description_of @expected_after}#{@description_suffix}"
+        end
+      end
+
+      # @private
+      # Encapsulates the details of the before/after values.
+      class ChangeDetails
+        attr_reader :message, :actual_before, :actual_after
+
+        def initialize(receiver=nil, message=nil, &block)
+          if receiver && !message
+            raise(
+              ArgumentError,
+              "`change` requires either an object and message " \
+              "(`change(obj, :msg)`) or a block (`change { }`). " \
+              "You passed an object but no message."
+            )
+          end
+          @message    = message ? "##{message}" : "result"
+          @value_proc = block || lambda { receiver.__send__(message) }
+        end
+
+        def perform_change(event_proc)
+          @actual_before = evaluate_value_proc
+          event_proc.call
+          @actual_after = evaluate_value_proc
+        end
+
+        def changed?
+          @actual_before != @actual_after
+        end
+
+        def actual_delta
+          @actual_after - @actual_before
+        end
+
+      private
+
+        def evaluate_value_proc
+          case val = @value_proc.call
+          when IO # enumerable, but we don't want to dup it.
+            val
+          when Enumerable, String
+            val.dup
+          else
+            val
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/compound.rb b/rspec-expectations/lib/rspec/matchers/built_in/compound.rb
new file mode 100644
index 0000000..2479864
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/compound.rb
@@ -0,0 +1,293 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Base class for `and` and `or` compound matchers.
+      # rubocop:disable ClassLength
+      class Compound < BaseMatcher
+        # @private
+        attr_reader :matcher_1, :matcher_2, :evaluator
+
+        def initialize(matcher_1, matcher_2)
+          @matcher_1 = matcher_1
+          @matcher_2 = matcher_2
+        end
+
+        # @private
+        def does_not_match?(_actual)
+          raise NotImplementedError, "`expect(...).not_to matcher.#{conjunction} matcher` " \
+            "is not supported, since it creates a bit of an ambiguity. Instead, define negated versions " \
+            "of whatever matchers you wish to negate with `RSpec::Matchers.define_negated_matcher` and " \
+            "use `expect(...).to matcher.#{conjunction} matcher`."
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          singleline_message(matcher_1.description, matcher_2.description)
+        end
+
+        def supports_block_expectations?
+          matcher_supports_block_expectations?(matcher_1) &&
+          matcher_supports_block_expectations?(matcher_2)
+        end
+
+        def expects_call_stack_jump?
+          NestedEvaluator.matcher_expects_call_stack_jump?(matcher_1) ||
+          NestedEvaluator.matcher_expects_call_stack_jump?(matcher_2)
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          matcher_is_diffable?(matcher_1) || matcher_is_diffable?(matcher_2)
+        end
+
+        # @api private
+        # @return [RSpec::Matchers::ExpectedsForMultipleDiffs]
+        def expected
+          return nil unless evaluator
+          ::RSpec::Matchers::ExpectedsForMultipleDiffs.for_many_matchers(diffable_matcher_list)
+        end
+
+      protected
+
+        def diffable_matcher_list
+          list = []
+          list.concat(diffable_matcher_list_for(matcher_1)) unless matcher_1_matches?
+          list.concat(diffable_matcher_list_for(matcher_2)) unless matcher_2_matches?
+          list
+        end
+
+      private
+
+        def initialize_copy(other)
+          @matcher_1 = @matcher_1.clone
+          @matcher_2 = @matcher_2.clone
+          super
+        end
+
+        def match(_expected, actual)
+          evaluator_klass = if supports_block_expectations? && Proc === actual
+                              NestedEvaluator
+                            else
+                              SequentialEvaluator
+                            end
+
+          @evaluator = evaluator_klass.new(actual, matcher_1, matcher_2)
+        end
+
+        def indent_multiline_message(message)
+          message.lines.map do |line|
+            line =~ /\S/ ? '   ' + line : line
+          end.join
+        end
+
+        def compound_failure_message
+          message_1 = matcher_1.failure_message
+          message_2 = matcher_2.failure_message
+
+          if multiline?(message_1) || multiline?(message_2)
+            multiline_message(message_1, message_2)
+          else
+            singleline_message(message_1, message_2)
+          end
+        end
+
+        def multiline_message(message_1, message_2)
+          [
+            indent_multiline_message(message_1.sub(/\n+\z/, '')),
+            "...#{conjunction}:",
+            indent_multiline_message(message_2.sub(/\A\n+/, ''))
+          ].join("\n\n")
+        end
+
+        def multiline?(message)
+          message.lines.count > 1
+        end
+
+        def singleline_message(message_1, message_2)
+          [message_1, conjunction, message_2].join(' ')
+        end
+
+        def matcher_1_matches?
+          evaluator.matcher_matches?(matcher_1)
+        end
+
+        def matcher_2_matches?
+          evaluator.matcher_matches?(matcher_2)
+        end
+
+        def matcher_supports_block_expectations?(matcher)
+          matcher.supports_block_expectations?
+        rescue NoMethodError
+          false
+        end
+
+        def matcher_is_diffable?(matcher)
+          matcher.diffable?
+        rescue NoMethodError
+          false
+        end
+
+        def diffable_matcher_list_for(matcher)
+          return [] unless matcher_is_diffable?(matcher)
+          return matcher.diffable_matcher_list if Compound === matcher
+          [matcher]
+        end
+
+        # For value expectations, we can evaluate the matchers sequentially.
+        class SequentialEvaluator
+          def initialize(actual, *)
+            @actual = actual
+          end
+
+          def matcher_matches?(matcher)
+            matcher.matches?(@actual)
+          end
+        end
+
+        # Normally, we evaluate the matching sequentially. For an expression like
+        # `expect(x).to foo.and bar`, this becomes:
+        #
+        #   expect(x).to foo
+        #   expect(x).to bar
+        #
+        # For block expectations, we need to nest them instead, so that
+        # `expect { x }.to foo.and bar` becomes:
+        #
+        #   expect {
+        #     expect { x }.to foo
+        #   }.to bar
+        #
+        # This is necessary so that the `expect` block is only executed once.
+        class NestedEvaluator
+          def initialize(actual, matcher_1, matcher_2)
+            @actual        = actual
+            @matcher_1     = matcher_1
+            @matcher_2     = matcher_2
+            @match_results = {}
+
+            inner, outer = order_block_matchers
+
+            @match_results[outer] = outer.matches?(Proc.new do |*args|
+              @match_results[inner] = inner.matches?(inner_matcher_block(args))
+            end)
+          end
+
+          def matcher_matches?(matcher)
+            @match_results.fetch(matcher)
+          end
+
+        private
+
+          # Some block matchers (such as `yield_xyz`) pass args to the `expect` block.
+          # When such a matcher is used as the outer matcher, we need to forward the
+          # the args on to the `expect` block.
+          def inner_matcher_block(outer_args)
+            return @actual if outer_args.empty?
+
+            Proc.new do |*inner_args|
+              unless inner_args.empty?
+                raise ArgumentError, "(#{@matcher_1.description}) and " \
+                  "(#{@matcher_2.description}) cannot be combined in a compound expectation " \
+                  "since both matchers pass arguments to the block."
+              end
+
+              @actual.call(*outer_args)
+            end
+          end
+
+          # For a matcher like `raise_error` or `throw_symbol`, where the block will jump
+          # up the call stack, we need to order things so that it is the inner matcher.
+          # For example, we need it to be this:
+          #
+          #   expect {
+          #     expect {
+          #       x += 1
+          #       raise "boom"
+          #     }.to raise_error("boom")
+          #   }.to change { x }.by(1)
+          #
+          # ...rather than:
+          #
+          #   expect {
+          #     expect {
+          #       x += 1
+          #       raise "boom"
+          #     }.to change { x }.by(1)
+          #   }.to raise_error("boom")
+          #
+          # In the latter case, the after-block logic in the `change` matcher would never
+          # get executed because the `raise "boom"` line would jump to the `rescue` in the
+          # `raise_error` logic, so only the former case will work properly.
+          #
+          # This method figures out which matcher should be the inner matcher and which
+          # should be the outer matcher.
+          def order_block_matchers
+            return @matcher_1, @matcher_2 unless self.class.matcher_expects_call_stack_jump?(@matcher_2)
+            return @matcher_2, @matcher_1 unless self.class.matcher_expects_call_stack_jump?(@matcher_1)
+
+            raise ArgumentError, "(#{@matcher_1.description}) and " \
+              "(#{@matcher_2.description}) cannot be combined in a compound expectation " \
+              "because they both expect a call stack jump."
+          end
+
+          def self.matcher_expects_call_stack_jump?(matcher)
+            matcher.expects_call_stack_jump?
+          rescue NoMethodError
+            false
+          end
+        end
+
+        # @api public
+        # Matcher used to represent a compound `and` expectation.
+        class And < self
+          # @api private
+          # @return [String]
+          def failure_message
+            if matcher_1_matches?
+              matcher_2.failure_message
+            elsif matcher_2_matches?
+              matcher_1.failure_message
+            else
+              compound_failure_message
+            end
+          end
+
+        private
+
+          def match(*)
+            super
+            matcher_1_matches? && matcher_2_matches?
+          end
+
+          def conjunction
+            "and"
+          end
+        end
+
+        # @api public
+        # Matcher used to represent a compound `or` expectation.
+        class Or < self
+          # @api private
+          # @return [String]
+          def failure_message
+            compound_failure_message
+          end
+
+        private
+
+          def match(*)
+            super
+            matcher_1_matches? || matcher_2_matches?
+          end
+
+          def conjunction
+            "or"
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/contain_exactly.rb b/rspec-expectations/lib/rspec/matchers/built_in/contain_exactly.rb
new file mode 100644
index 0000000..7b0a3ce
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/contain_exactly.rb
@@ -0,0 +1,249 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `contain_exactly` and `match_array`.
+      # Not intended to be instantiated directly.
+      class ContainExactly < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          if Array === actual
+            message  = "expected collection contained:  #{safe_sort(surface_descriptions_in expected).inspect}\n"
+            message += "actual collection contained:    #{safe_sort(actual).inspect}\n"
+            message += "the missing elements were:      #{safe_sort(surface_descriptions_in missing_items).inspect}\n" unless missing_items.empty?
+            message += "the extra elements were:        #{safe_sort(extra_items).inspect}\n" unless extra_items.empty?
+            message
+          else
+            "expected a collection that can be converted to an array with " \
+            "`#to_ary` or `#to_a`, but got #{actual.inspect}"
+          end
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{actual.inspect} not to contain exactly#{to_sentence(surface_descriptions_in expected)}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "contain exactly#{to_sentence(surface_descriptions_in expected)}"
+        end
+
+      private
+
+        def match(_expected, _actual)
+          return false unless convert_actual_to_an_array
+          match_when_sorted? || (extra_items.empty? && missing_items.empty?)
+        end
+
+        # This cannot always work (e.g. when dealing with unsortable items,
+        # or matchers as expected items), but it's practically free compared to
+        # the slowness of the full matching algorithm, and in common cases this
+        # works, so it's worth a try.
+        def match_when_sorted?
+          values_match?(safe_sort(expected), safe_sort(actual))
+        end
+
+        def convert_actual_to_an_array
+          if actual.respond_to?(:to_ary)
+            @actual = actual.to_ary
+          elsif enumerable?(actual) && actual.respond_to?(:to_a)
+            @actual = actual.to_a
+          else
+            return false
+          end
+        end
+
+        def safe_sort(array)
+          array.sort rescue array
+        end
+
+        def missing_items
+          @missing_items ||= best_solution.unmatched_expected_indexes.map do |index|
+            expected[index]
+          end
+        end
+
+        def extra_items
+          @extra_items ||= best_solution.unmatched_actual_indexes.map do |index|
+            actual[index]
+          end
+        end
+
+        def best_solution
+          @best_solution ||= pairings_maximizer.find_best_solution
+        end
+
+        def pairings_maximizer
+          @pairings_maximizer ||= begin
+            expected_matches = Hash[Array.new(expected.size) { |i| [i, []] }]
+            actual_matches   = Hash[Array.new(actual.size)   { |i| [i, []] }]
+
+            expected.each_with_index do |e, ei|
+              actual.each_with_index do |a, ai|
+                next unless values_match?(e, a)
+
+                expected_matches[ei] << ai
+                actual_matches[ai] << ei
+              end
+            end
+
+            PairingsMaximizer.new(expected_matches, actual_matches)
+          end
+        end
+
+        # Once we started supporting composing matchers, the algorithm for this matcher got
+        # much more complicated. Consider this expression:
+        #
+        #   expect(["fool", "food"]).to contain_exactly(/foo/, /fool/)
+        #
+        # This should pass (because we can pair /fool/ with "fool" and /foo/ with "food"), but
+        # the original algorithm used by this matcher would pair the first elements it could
+        # (/foo/ with "fool"), which would leave /fool/ and "food" unmatched.  When we have
+        # an expected element which is a matcher that matches a superset of actual items
+        # compared to another expected element matcher, we need to consider every possible pairing.
+        #
+        # This class is designed to maximize the number of actual/expected pairings -- or,
+        # conversely, to minimize the number of unpaired items. It's essentially a brute
+        # force solution, but with a few heuristics applied to reduce the size of the
+        # problem space:
+        #
+        #   * Any items which match none of the items in the other list are immediately
+        #     placed into the `unmatched_expected_indexes` or `unmatched_actual_indexes` array.
+        #     The extra items and missing items in the matcher failure message are derived
+        #     from these arrays.
+        #   * Any items which reciprocally match only each other are paired up and not
+        #     considered further.
+        #
+        # What's left is only the items which match multiple items from the other list
+        # (or vice versa). From here, it performs a brute-force depth-first search,
+        # looking for a solution which pairs all elements in both lists, or, barring that,
+        # that produces the fewest unmatched items.
+        #
+        # @private
+        class PairingsMaximizer
+          Solution = Struct.new(:unmatched_expected_indexes,     :unmatched_actual_indexes,
+                                :indeterminate_expected_indexes, :indeterminate_actual_indexes) do
+            def worse_than?(other)
+              unmatched_item_count > other.unmatched_item_count
+            end
+
+            def candidate?
+              indeterminate_expected_indexes.empty? &&
+              indeterminate_actual_indexes.empty?
+            end
+
+            def ideal?
+              candidate? && (
+                unmatched_expected_indexes.empty? ||
+                unmatched_actual_indexes.empty?
+              )
+            end
+
+            def unmatched_item_count
+              unmatched_expected_indexes.count + unmatched_actual_indexes.count
+            end
+
+            def +(derived_candidate_solution)
+              self.class.new(
+                unmatched_expected_indexes + derived_candidate_solution.unmatched_expected_indexes,
+                unmatched_actual_indexes   + derived_candidate_solution.unmatched_actual_indexes,
+                # Ignore the indeterminate indexes: by the time we get here,
+                # we've dealt with all indeterminates.
+                [], []
+              )
+            end
+          end
+
+          attr_reader :expected_to_actual_matched_indexes, :actual_to_expected_matched_indexes, :solution
+
+          def initialize(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes)
+            @expected_to_actual_matched_indexes = expected_to_actual_matched_indexes
+            @actual_to_expected_matched_indexes = actual_to_expected_matched_indexes
+
+            unmatched_expected_indexes, indeterminate_expected_indexes =
+              categorize_indexes(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes)
+
+            unmatched_actual_indexes, indeterminate_actual_indexes =
+              categorize_indexes(actual_to_expected_matched_indexes, expected_to_actual_matched_indexes)
+
+            @solution = Solution.new(unmatched_expected_indexes,     unmatched_actual_indexes,
+                                     indeterminate_expected_indexes, indeterminate_actual_indexes)
+          end
+
+          def find_best_solution
+            return solution if solution.candidate?
+            best_solution_so_far = NullSolution
+
+            expected_index = solution.indeterminate_expected_indexes.first
+            actuals = expected_to_actual_matched_indexes[expected_index]
+
+            actuals.each do |actual_index|
+              solution = best_solution_for_pairing(expected_index, actual_index)
+              return solution if solution.ideal?
+              best_solution_so_far = solution if best_solution_so_far.worse_than?(solution)
+            end
+
+            best_solution_so_far
+          end
+
+        private
+
+          # @private
+          # Starting solution that is worse than any other real solution.
+          NullSolution = Class.new do
+            def self.worse_than?(_other)
+              true
+            end
+          end
+
+          def categorize_indexes(indexes_to_categorize, other_indexes)
+            unmatched     = []
+            indeterminate = []
+
+            indexes_to_categorize.each_pair do |index, matches|
+              if matches.empty?
+                unmatched << index
+              elsif !reciprocal_single_match?(matches, index, other_indexes)
+                indeterminate << index
+              end
+            end
+
+            return unmatched, indeterminate
+          end
+
+          def reciprocal_single_match?(matches, index, other_list)
+            return false unless matches.one?
+            other_list[matches.first] == [index]
+          end
+
+          def best_solution_for_pairing(expected_index, actual_index)
+            modified_expecteds = apply_pairing_to(
+              solution.indeterminate_expected_indexes,
+              expected_to_actual_matched_indexes, actual_index)
+
+            modified_expecteds.delete(expected_index)
+
+            modified_actuals   = apply_pairing_to(
+              solution.indeterminate_actual_indexes,
+              actual_to_expected_matched_indexes, expected_index)
+
+            modified_actuals.delete(actual_index)
+
+            solution + self.class.new(modified_expecteds, modified_actuals).find_best_solution
+          end
+
+          def apply_pairing_to(indeterminates, original_matches, other_list_index)
+            indeterminates.inject({}) do |accum, index|
+              accum[index] = original_matches[index] - [other_list_index]
+              accum
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/cover.rb b/rspec-expectations/lib/rspec/matchers/built_in/cover.rb
new file mode 100644
index 0000000..47474a2
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/cover.rb
@@ -0,0 +1,24 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `cover`.
+      # Not intended to be instantiated directly.
+      class Cover < BaseMatcher
+        def initialize(*expected)
+          @expected = expected
+        end
+
+        def matches?(range)
+          @actual = range
+          @expected.all? { |e| range.cover?(e) }
+        end
+
+        def does_not_match?(range)
+          @actual = range
+          expected.none? { |e| range.cover?(e) }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/eq.rb b/rspec-expectations/lib/rspec/matchers/built_in/eq.rb
new file mode 100644
index 0000000..67bc22a
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/eq.rb
@@ -0,0 +1,75 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `eq`.
+      # Not intended to be instantiated directly.
+      class Eq < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          "\nexpected: #{format_object(expected)}\n     got: #{format_object(actual)}\n\n(compared using ==)\n"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "\nexpected: value != #{format_object(expected)}\n     got: #{format_object(actual)}\n\n(compared using ==)\n"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "#{name_to_sentence} #{@expected.inspect}"
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          true
+        end
+
+      private
+
+        def match(expected, actual)
+          actual == expected
+        end
+
+        def format_object(object)
+          if Time === object
+            format_time(object)
+          elsif defined?(DateTime) && DateTime === object
+            format_date_time(object)
+          elsif defined?(BigDecimal) && BigDecimal === object
+            "#{object.to_s 'F'} (#{object.inspect})"
+          else
+            object.inspect
+          end
+        end
+
+        TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
+
+        if Time.method_defined?(:nsec)
+          def format_time(time)
+            time.strftime("#{TIME_FORMAT}.#{"%09d" % time.nsec} %z")
+          end
+        else # for 1.8.7
+          def format_time(time)
+            time.strftime("#{TIME_FORMAT}.#{"%06d" % time.usec} %z")
+          end
+        end
+
+        DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S.%N %z"
+        # ActiveSupport sometimes overrides inspect. If `ActiveSupport` is
+        # defined use a custom format string that includes more time precision.
+        def format_date_time(date_time)
+          if defined?(ActiveSupport)
+            date_time.strftime(DATE_TIME_FORMAT)
+          else
+            date_time.inspect
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/eql.rb b/rspec-expectations/lib/rspec/matchers/built_in/eql.rb
new file mode 100644
index 0000000..4aee572
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/eql.rb
@@ -0,0 +1,34 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `eql`.
+      # Not intended to be instantiated directly.
+      class Eql < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          "\nexpected: #{expected.inspect}\n     got: #{actual.inspect}\n\n(compared using eql?)\n"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "\nexpected: value != #{expected.inspect}\n     got: #{actual.inspect}\n\n(compared using eql?)\n"
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          true
+        end
+
+      private
+
+        def match(expected, actual)
+          actual.eql? expected
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/equal.rb b/rspec-expectations/lib/rspec/matchers/built_in/equal.rb
new file mode 100644
index 0000000..e2e02d0
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/equal.rb
@@ -0,0 +1,81 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `equal`.
+      # Not intended to be instantiated directly.
+      class Equal < BaseMatcher
+        # @api private
+        # @return [String]
+        def failure_message
+          if expected_is_a_literal_singleton?
+            simple_failure_message
+          else
+            detailed_failure_message
+          end
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          <<-MESSAGE
+
+expected not #{inspect_object(actual)}
+         got #{inspect_object(expected)}
+
+Compared using equal?, which compares object identity.
+
+MESSAGE
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          !expected_is_a_literal_singleton?
+        end
+
+      private
+
+        def match(expected, actual)
+          actual.equal? expected
+        end
+
+        LITERAL_SINGLETONS = [true, false, nil]
+
+        def expected_is_a_literal_singleton?
+          LITERAL_SINGLETONS.include?(expected)
+        end
+
+        def actual_inspected
+          if LITERAL_SINGLETONS.include?(actual)
+            actual.inspect
+          else
+            inspect_object(actual)
+          end
+        end
+
+        def simple_failure_message
+          "\nexpected #{expected.inspect}\n     got #{actual_inspected}\n"
+        end
+
+        def detailed_failure_message
+          <<-MESSAGE
+
+expected #{inspect_object(expected)}
+     got #{inspect_object(actual)}
+
+Compared using equal?, which compares object identity,
+but expected and actual are not the same object. Use
+`expect(actual).to eq(expected)` if you don't care about
+object identity in this example.
+
+MESSAGE
+        end
+
+        def inspect_object(o)
+          "#<#{o.class}:#{o.object_id}> => #{o.inspect}"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/exist.rb b/rspec-expectations/lib/rspec/matchers/built_in/exist.rb
new file mode 100644
index 0000000..2884fab
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/exist.rb
@@ -0,0 +1,86 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `exist`.
+      # Not intended to be instantiated directly.
+      class Exist < BaseMatcher
+        def initialize(*expected)
+          @expected = expected
+        end
+
+        # @api private
+        # @return [Boolean]
+        def matches?(actual)
+          @actual = actual
+          @test = ExistenceTest.new @actual, @expected
+          @test.valid_test? && @test.actual_exists?
+        end
+
+        # @api private
+        # @return [Boolean]
+        def does_not_match?(actual)
+          @actual = actual
+          @test = ExistenceTest.new @actual, @expected
+          @test.valid_test? && !@test.actual_exists?
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{@actual.inspect} to exist#{@test.validity_message}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{@actual.inspect} not to exist#{@test.validity_message}"
+        end
+
+        # @api private
+        # Simple class for memoizing actual/expected for this matcher
+        # and examining the match
+        class ExistenceTest < Struct.new(:actual, :expected)
+          # @api private
+          # @return [Boolean]
+          def valid_test?
+            uniq_truthy_values.size == 1
+          end
+
+          # @api private
+          # @return [Boolean]
+          def actual_exists?
+            existence_values.first
+          end
+
+          # @api private
+          # @return [String]
+          def validity_message
+            case uniq_truthy_values.size
+            when 0
+              " but it does not respond to either `exist?` or `exists?`"
+            when 2
+              " but `exist?` and `exists?` returned different values:\n\n"\
+              " exist?: #{existence_values.first}\n"\
+              "exists?: #{existence_values.last}"
+            end
+          end
+
+        private
+
+          def uniq_truthy_values
+            @uniq_truthy_values ||= existence_values.map { |v| !!v }.uniq
+          end
+
+          def existence_values
+            @existence_values ||= predicates.map { |p| actual.__send__(p, *expected) }
+          end
+
+          def predicates
+            @predicates ||= [:exist?, :exists?].select { |p| actual.respond_to?(p) }
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/has.rb b/rspec-expectations/lib/rspec/matchers/built_in/has.rb
new file mode 100644
index 0000000..f37cfcf
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/has.rb
@@ -0,0 +1,101 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `has_<predicate>`.
+      # Not intended to be instantiated directly.
+      class Has < BaseMatcher
+        def initialize(method_name, *args, &block)
+          @method_name, @args, @block = method_name, args, block
+        end
+
+        # @private
+        def matches?(actual, &block)
+          @actual = actual
+          @block ||= block
+          predicate_accessible? && predicate_matches?
+        end
+
+        # @private
+        def does_not_match?(actual, &block)
+          @actual = actual
+          @block ||= block
+          predicate_accessible? && !predicate_matches?
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          validity_message || "expected ##{predicate}#{failure_message_args_description} to return true, got false"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          validity_message || "expected ##{predicate}#{failure_message_args_description} to return false, got true"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          [method_description, args_description].compact.join(' ')
+        end
+
+      private
+
+        def predicate_accessible?
+          !private_predicate? && predicate_exists?
+        end
+
+        # support 1.8.7, evaluate once at load time for performance
+        if String === methods.first
+          def private_predicate?
+            @actual.private_methods.include? predicate.to_s
+          end
+        else
+          def private_predicate?
+            @actual.private_methods.include? predicate
+          end
+        end
+
+        def predicate_exists?
+          @actual.respond_to? predicate
+        end
+
+        def predicate_matches?
+          @actual.__send__(predicate, *@args, &@block)
+        end
+
+        def predicate
+          # On 1.9, there appears to be a bug where String#match can return `false`
+          # rather than the match data object. Changing to Regex#match appears to
+          # work around this bug. For an example of this bug, see:
+          # https://travis-ci.org/rspec/rspec-expectations/jobs/27549635
+          @predicate ||= :"has_#{Matchers::HAS_REGEX.match(@method_name.to_s).captures.first}?"
+        end
+
+        def method_description
+          @method_name.to_s.gsub('_', ' ')
+        end
+
+        def args_description
+          return nil if @args.empty?
+          @args.map { |arg| arg.inspect }.join(', ')
+        end
+
+        def failure_message_args_description
+          desc = args_description
+          "(#{desc})" if desc
+        end
+
+        def validity_message
+          if private_predicate?
+            "expected #{@actual} to respond to `#{predicate}` but `#{predicate}` is a private method"
+          elsif !predicate_exists?
+            "expected #{@actual} to respond to `#{predicate}`"
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/have_attributes.rb b/rspec-expectations/lib/rspec/matchers/built_in/have_attributes.rb
new file mode 100644
index 0000000..3b0faed
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/have_attributes.rb
@@ -0,0 +1,113 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `have_attributes`.
+      # Not intended to be instantiated directly.
+      class HaveAttributes < BaseMatcher
+        # @private
+        attr_reader :respond_to_failed
+
+        def initialize(expected)
+          @expected = expected
+          @values = {}
+          @respond_to_failed = false
+          @negated = false
+        end
+
+        # @private
+        def actual
+          @values
+        end
+
+        # @api private
+        # @return [Boolean]
+        def matches?(actual)
+          @actual = actual
+          @negated = false
+          return false unless respond_to_attributes?
+          perform_match(:all?)
+        end
+
+        # @api private
+        # @return [Boolean]
+        def does_not_match?(actual)
+          @actual = actual
+          @negated = true
+          return false unless respond_to_attributes?
+          perform_match(:none?)
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          described_items = surface_descriptions_in(expected)
+          improve_hash_formatting "have attributes #{described_items.inspect}"
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          !@respond_to_failed && !@negated
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          respond_to_failure_message_or do
+            "expected #{@actual.inspect} to #{description} but had attributes #{ formatted_values }"
+          end
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          respond_to_failure_message_or { "expected #{@actual.inspect} not to #{description}" }
+        end
+
+      private
+
+        def cache_all_values
+          @values = {}
+          expected.each do |attribute_key, _attribute_value|
+            actual_value = @actual.__send__(attribute_key)
+            @values[attribute_key] = actual_value
+          end
+        end
+
+        def perform_match(predicate)
+          cache_all_values
+          expected.__send__(predicate) do |attribute_key, attribute_value|
+            actual_has_attribute?(attribute_key, attribute_value)
+          end
+        end
+
+        def actual_has_attribute?(attribute_key, attribute_value)
+          values_match?(attribute_value, @values.fetch(attribute_key))
+        end
+
+        def respond_to_attributes?
+          matches = respond_to_matcher.matches?(@actual)
+          @respond_to_failed = !matches
+          matches
+        end
+
+        def respond_to_matcher
+          @respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments
+        end
+
+        def respond_to_failure_message_or
+          if respond_to_failed
+            respond_to_matcher.failure_message
+          else
+            improve_hash_formatting(yield)
+          end
+        end
+
+        def formatted_values
+          improve_hash_formatting(@values.inspect)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/include.rb b/rspec-expectations/lib/rspec/matchers/built_in/include.rb
new file mode 100644
index 0000000..702a266
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/include.rb
@@ -0,0 +1,105 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `include`.
+      # Not intended to be instantiated directly.
+      class Include < BaseMatcher
+        def initialize(*expected)
+          @expected = expected
+        end
+
+        # @api private
+        # @return [Boolean]
+        def matches?(actual)
+          @actual = actual
+          perform_match(:all?, :all?)
+        end
+
+        # @api private
+        # @return [Boolean]
+        def does_not_match?(actual)
+          @actual = actual
+          perform_match(:none?, :any?)
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          described_items = surface_descriptions_in(expected)
+          improve_hash_formatting "include#{to_sentence(described_items)}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          improve_hash_formatting(super) + invalid_object_message
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          improve_hash_formatting(super) + invalid_object_message
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          true
+        end
+
+      private
+
+        def invalid_object_message
+          return '' if actual.respond_to?(:include?)
+          ", but it does not respond to `include?`"
+        end
+
+        def perform_match(predicate, hash_subset_predicate)
+          return false unless actual.respond_to?(:include?)
+
+          expected.__send__(predicate) do |expected_item|
+            if comparing_hash_to_a_subset?(expected_item)
+              expected_item.__send__(hash_subset_predicate) do |(key, value)|
+                actual_hash_includes?(key, value)
+              end
+            elsif comparing_hash_keys?(expected_item)
+              actual_hash_has_key?(expected_item)
+            else
+              actual_collection_includes?(expected_item)
+            end
+          end
+        end
+
+        def comparing_hash_to_a_subset?(expected_item)
+          actual.is_a?(Hash) && expected_item.is_a?(Hash)
+        end
+
+        def actual_hash_includes?(expected_key, expected_value)
+          actual_value = actual.fetch(expected_key) { return false }
+          values_match?(expected_value, actual_value)
+        end
+
+        def comparing_hash_keys?(expected_item)
+          actual.is_a?(Hash) && !expected_item.is_a?(Hash)
+        end
+
+        def actual_hash_has_key?(expected_key)
+          # We check `key?` first for perf:
+          # `key?` is O(1), but `any?` is O(N).
+          actual.key?(expected_key) ||
+          actual.keys.any? { |key| values_match?(expected_key, key) }
+        end
+
+        def actual_collection_includes?(expected_item)
+          return true if actual.include?(expected_item)
+
+          # String lacks an `any?` method...
+          return false unless actual.respond_to?(:any?)
+
+          actual.any? { |value| values_match?(expected_item, value) }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/match.rb b/rspec-expectations/lib/rspec/matchers/built_in/match.rb
new file mode 100644
index 0000000..9e44e8d
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/match.rb
@@ -0,0 +1,29 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `match`.
+      # Not intended to be instantiated directly.
+      class Match < BaseMatcher
+        # @api private
+        # @return [String]
+        def description
+          "match #{surface_descriptions_in(expected).inspect}"
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          true
+        end
+
+      private
+
+        def match(expected, actual)
+          return true if values_match?(expected, actual)
+          actual.match(expected) if actual.respond_to?(:match)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/operators.rb b/rspec-expectations/lib/rspec/matchers/built_in/operators.rb
new file mode 100644
index 0000000..eada4b5
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/operators.rb
@@ -0,0 +1,119 @@
+require 'rspec/support'
+
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for operator matchers.
+      # Not intended to be instantiated directly.
+      # Only available for use with `should`.
+      class OperatorMatcher
+        class << self
+          # @private
+          def registry
+            @registry ||= {}
+          end
+
+          # @private
+          def register(klass, operator, matcher)
+            registry[klass] ||= {}
+            registry[klass][operator] = matcher
+          end
+
+          # @private
+          def unregister(klass, operator)
+            registry[klass] && registry[klass].delete(operator)
+          end
+
+          # @private
+          def get(klass, operator)
+            klass.ancestors.each do |ancestor|
+              matcher = registry[ancestor] && registry[ancestor][operator]
+              return matcher if matcher
+            end
+
+            nil
+          end
+        end
+
+        register Enumerable, '=~', BuiltIn::ContainExactly
+
+        def initialize(actual)
+          @actual = actual
+        end
+
+        # @private
+        def self.use_custom_matcher_or_delegate(operator)
+          define_method(operator) do |expected|
+            if !has_non_generic_implementation_of?(operator) && (matcher = OperatorMatcher.get(@actual.class, operator))
+              @actual.__send__(::RSpec::Matchers.last_expectation_handler.should_method, matcher.new(expected))
+            else
+              eval_match(@actual, operator, expected)
+            end
+          end
+
+          negative_operator = operator.sub(/^=/, '!')
+          if negative_operator != operator && respond_to?(negative_operator)
+            define_method(negative_operator) do |_expected|
+              opposite_should = ::RSpec::Matchers.last_expectation_handler.opposite_should_method
+              raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`.  " \
+                "Use `#{opposite_should} #{operator} expected` instead."
+            end
+          end
+        end
+
+        ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator|
+          use_custom_matcher_or_delegate operator
+        end
+
+        # @private
+        def fail_with_message(message)
+          RSpec::Expectations.fail_with(message, @expected, @actual)
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "#{@operator} #{@expected.inspect}"
+        end
+
+      private
+
+        def has_non_generic_implementation_of?(op)
+          Support.method_handle_for(@actual, op).owner != ::Kernel
+        rescue NameError
+          false
+        end
+
+        def eval_match(actual, operator, expected)
+          ::RSpec::Matchers.last_matcher = self
+          @operator, @expected = operator, expected
+          __delegate_operator(actual, operator, expected)
+        end
+      end
+
+      # @private
+      # Handles operator matcher for `should`.
+      class PositiveOperatorMatcher < OperatorMatcher
+        def __delegate_operator(actual, operator, expected)
+          if actual.__send__(operator, expected)
+            true
+          elsif ['==', '===', '=~'].include?(operator)
+            fail_with_message("expected: #{expected.inspect}\n     got: #{actual.inspect} (using #{operator})")
+          else
+            fail_with_message("expected: #{operator} #{expected.inspect}\n     got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
+          end
+        end
+      end
+
+      # @private
+      # Handles operator matcher for `should_not`.
+      class NegativeOperatorMatcher < OperatorMatcher
+        def __delegate_operator(actual, operator, expected)
+          return false unless actual.__send__(operator, expected)
+          fail_with_message("expected not: #{operator} #{expected.inspect}\n         got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/output.rb b/rspec-expectations/lib/rspec/matchers/built_in/output.rb
new file mode 100644
index 0000000..b4b168d
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/output.rb
@@ -0,0 +1,193 @@
+require 'stringio'
+require 'tempfile'
+
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `output`.
+      # Not intended to be instantiated directly.
+      class Output < BaseMatcher
+        def initialize(expected)
+          @expected        = expected
+          @actual          = ""
+          @block           = nil
+          @stream_capturer = NullCapture
+        end
+
+        def matches?(block)
+          @block = block
+          return false unless Proc === block
+          @actual = @stream_capturer.capture(block)
+          @expected ? values_match?(@expected, @actual) : captured?
+        end
+
+        def does_not_match?(block)
+          !matches?(block) && Proc === block
+        end
+
+        # @api public
+        # Tells the matcher to match against stdout.
+        # Works only when the main Ruby process prints to stdout
+        def to_stdout
+          @stream_capturer = CaptureStdout
+          self
+        end
+
+        # @api public
+        # Tells the matcher to match against stderr.
+        # Works only when the main Ruby process prints to stderr
+        def to_stderr
+          @stream_capturer = CaptureStderr
+          self
+        end
+
+        # @api public
+        # Tells the matcher to match against stdout.
+        # Works when subprocesses print to stdout as well.
+        # This is significantly (~30x) slower than `to_stdout`
+        def to_stdout_from_any_process
+          @stream_capturer = CaptureStreamToTempfile.new("stdout", $stdout)
+          self
+        end
+
+        # @api public
+        # Tells the matcher to match against stderr.
+        # Works when subprocesses print to stderr as well.
+        # This is significantly (~30x) slower than `to_stderr`
+        def to_stderr_from_any_process
+          @stream_capturer = CaptureStreamToTempfile.new("stderr", $stderr)
+          self
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected block to #{description}, but #{positive_failure_reason}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected block to not #{description}, but #{negative_failure_reason}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          if @expected
+            "output #{description_of @expected} to #{@stream_capturer.name}"
+          else
+            "output to #{@stream_capturer.name}"
+          end
+        end
+
+        # @api private
+        # @return [Boolean]
+        def diffable?
+          true
+        end
+
+        # @api private
+        # Indicates this matcher matches against a block.
+        # @return [True]
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def captured?
+          @actual.length > 0
+        end
+
+        def positive_failure_reason
+          return "was not a block" unless Proc === @block
+          return "output #{actual_output_description}" if @expected
+          "did not"
+        end
+
+        def negative_failure_reason
+          return "was not a block" unless Proc === @block
+          "output #{actual_output_description}"
+        end
+
+        def actual_output_description
+          return "nothing" unless captured?
+          @actual.inspect
+        end
+      end
+
+      # @private
+      module NullCapture
+        def self.name
+          "some stream"
+        end
+
+        def self.capture(_block)
+          raise "You must chain `to_stdout` or `to_stderr` off of the `output(...)` matcher."
+        end
+      end
+
+      # @private
+      module CaptureStdout
+        def self.name
+          'stdout'
+        end
+
+        def self.capture(block)
+          captured_stream = StringIO.new
+
+          original_stream = $stdout
+          $stdout = captured_stream
+
+          block.call
+
+          captured_stream.string
+        ensure
+          $stdout = original_stream
+        end
+      end
+
+      # @private
+      module CaptureStderr
+        def self.name
+          'stderr'
+        end
+
+        def self.capture(block)
+          captured_stream = StringIO.new
+
+          original_stream = $stderr
+          $stderr = captured_stream
+
+          block.call
+
+          captured_stream.string
+        ensure
+          $stderr = original_stream
+        end
+      end
+
+      # @private
+      class CaptureStreamToTempfile < Struct.new(:name, :stream)
+        def capture(block)
+          original_stream = stream.clone
+          captured_stream = Tempfile.new(name)
+
+          begin
+            captured_stream.sync = true
+            stream.reopen(captured_stream)
+            block.call
+            captured_stream.rewind
+            captured_stream.read
+          ensure
+            stream.reopen(original_stream)
+            captured_stream.close
+            captured_stream.unlink
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb b/rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb
new file mode 100644
index 0000000..b8e2bc0
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb
@@ -0,0 +1,174 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `raise_error`.
+      # Not intended to be instantiated directly.
+      # rubocop:disable ClassLength
+      class RaiseError
+        include Composable
+
+        def initialize(expected_error_or_message=Exception, expected_message=nil, &block)
+          @block = block
+          @actual_error = nil
+          case expected_error_or_message
+          when String, Regexp
+            @expected_error, @expected_message = Exception, expected_error_or_message
+          else
+            @expected_error, @expected_message = expected_error_or_message, expected_message
+          end
+        end
+
+        # @api public
+        # Specifies the expected error message.
+        def with_message(expected_message)
+          raise_message_already_set if @expected_message
+          @expected_message = expected_message
+          self
+        end
+
+        # rubocop:disable MethodLength
+        # @private
+        def matches?(given_proc, negative_expectation=false, &block)
+          @given_proc = given_proc
+          @block ||= block
+          @raised_expected_error = false
+          @with_expected_message = false
+          @eval_block = false
+          @eval_block_passed = false
+
+          return false unless Proc === given_proc
+
+          begin
+            given_proc.call
+          rescue Exception => @actual_error
+            if values_match?(@expected_error, @actual_error)
+              @raised_expected_error = true
+              @with_expected_message = verify_message
+            end
+          end
+
+          unless negative_expectation
+            eval_block if @raised_expected_error && @with_expected_message && @block
+          end
+
+          expectation_matched?
+        end
+        # rubocop:enable MethodLength
+
+        # @private
+        def does_not_match?(given_proc)
+          prevent_invalid_expectations
+          !matches?(given_proc, :negative_expectation) && Proc === given_proc
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+        def expects_call_stack_jump?
+          true
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          @eval_block ? @actual_error.message : "expected #{expected_error}#{given_error}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected no #{expected_error}#{given_error}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "raise #{expected_error}"
+        end
+
+      private
+
+        def expectation_matched?
+          error_and_message_match? && block_matches?
+        end
+
+        def error_and_message_match?
+          @raised_expected_error && @with_expected_message
+        end
+
+        def block_matches?
+          @eval_block ? @eval_block_passed : true
+        end
+
+        def eval_block
+          @eval_block = true
+          begin
+            @block[@actual_error]
+            @eval_block_passed = true
+          rescue Exception => err
+            @actual_error = err
+          end
+        end
+
+        def verify_message
+          return true if @expected_message.nil?
+          values_match?(@expected_message, @actual_error.message)
+        end
+
+        def prevent_invalid_expectations
+          what_to_raise = if expecting_specific_exception? && @expected_message
+                            "`expect { }.not_to raise_error(SpecificErrorClass, message)`"
+                          elsif expecting_specific_exception?
+                            "`expect { }.not_to raise_error(SpecificErrorClass)`"
+                          elsif @expected_message
+                            "`expect { }.not_to raise_error(message)`"
+                          end
+
+          return unless what_to_raise
+
+          specific_class_error = ArgumentError.new("#{what_to_raise} is not valid, use `expect { }.not_to raise_error` (with no args) instead")
+          raise specific_class_error
+        end
+
+        def expected_error
+          case @expected_message
+          when nil
+            description_of(@expected_error)
+          when Regexp
+            "#{@expected_error} with message matching #{@expected_message.inspect}"
+          else
+            "#{@expected_error} with #{description_of @expected_message}"
+          end
+        end
+
+        def format_backtrace(backtrace)
+          formatter = Matchers.configuration.backtrace_formatter
+          formatter.format_backtrace(backtrace)
+        end
+
+        def given_error
+          return " but was not given a block" unless Proc === @given_proc
+          return " but nothing was raised" unless @actual_error
+
+          backtrace = format_backtrace(@actual_error.backtrace)
+          [
+            ", got #{@actual_error.inspect} with backtrace:",
+            *backtrace
+          ].join("\n  # ")
+        end
+
+        def expecting_specific_exception?
+          @expected_error != Exception
+        end
+
+        def raise_message_already_set
+          raise "`expect { }.to raise_error(message).with_message(message)` is not valid. The matcher only allows the expected message to be specified once"
+        end
+      end
+      # rubocop:enable ClassLength
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/respond_to.rb b/rspec-expectations/lib/rspec/matchers/built_in/respond_to.rb
new file mode 100644
index 0000000..85c1164
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/respond_to.rb
@@ -0,0 +1,91 @@
+RSpec::Support.require_rspec_support "method_signature_verifier"
+
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `respond_to`.
+      # Not intended to be instantiated directly.
+      class RespondTo < BaseMatcher
+        def initialize(*names)
+          @names = names
+          @expected_arity = nil
+        end
+
+        # @api public
+        # Specifies the number of expected arguments.
+        #
+        # @example
+        #   expect(obj).to respond_to(:message).with(3).arguments
+        def with(n)
+          @expected_arity = n
+          self
+        end
+
+        # @api public
+        # No-op. Intended to be used as syntactic sugar when using `with`.
+        #
+        # @example
+        #   expect(obj).to respond_to(:message).with(3).arguments
+        def argument
+          self
+        end
+        alias :arguments :argument
+
+        # @private
+        def matches?(actual)
+          find_failing_method_names(actual, :reject).empty?
+        end
+
+        # @private
+        def does_not_match?(actual)
+          find_failing_method_names(actual, :select).empty?
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{@actual.inspect} to respond to #{@failing_method_names.map { |name| name.inspect }.join(', ')}#{with_arity}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          failure_message.sub(/to respond to/, 'not to respond to')
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "respond to #{pp_names}#{with_arity}"
+        end
+
+      private
+
+        def find_failing_method_names(actual, filter_method)
+          @actual = actual
+          @failing_method_names = @names.__send__(filter_method) do |name|
+            @actual.respond_to?(name) && matches_arity?(actual, name)
+          end
+        end
+
+        def matches_arity?(actual, name)
+          return true unless @expected_arity
+
+          signature = Support::MethodSignature.new(actual.method(name))
+          Support::StrictSignatureVerifier.new(signature, Array.new(@expected_arity)).valid?
+        end
+
+        def with_arity
+          return "" unless @expected_arity
+          " with #{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}"
+        end
+
+        def pp_names
+          # Ruby 1.9 returns the same thing for array.to_s as array.inspect, so just use array.inspect here
+          @names.length == 1 ? "##{@names.first}" : @names.inspect
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/satisfy.rb b/rspec-expectations/lib/rspec/matchers/built_in/satisfy.rb
new file mode 100644
index 0000000..d79a584
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/satisfy.rb
@@ -0,0 +1,39 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `satisfy`.
+      # Not intended to be instantiated directly.
+      class Satisfy < BaseMatcher
+        def initialize(&block)
+          @block = block
+        end
+
+        # @private
+        def matches?(actual, &block)
+          @block = block if block
+          @actual = actual
+          @block.call(actual)
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{@actual} to satisfy block"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{@actual} not to satisfy block"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "satisfy block"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/start_or_end_with.rb b/rspec-expectations/lib/rspec/matchers/built_in/start_or_end_with.rb
new file mode 100644
index 0000000..189298d
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/start_or_end_with.rb
@@ -0,0 +1,92 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Base class for the `end_with` and `start_with` matchers.
+      # Not intended to be instantiated directly.
+      class StartOrEndWith < BaseMatcher
+        def initialize(*expected)
+          @actual_does_not_have_ordered_elements = false
+          @expected = expected.length == 1 ? expected.first : expected
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          super.tap do |msg|
+            if @actual_does_not_have_ordered_elements
+              msg << ", but it does not have ordered elements"
+            elsif !actual.respond_to?(:[])
+              msg << ", but it cannot be indexed using #[]"
+            end
+          end
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          return super unless Hash === expected
+          "#{name_to_sentence} #{surface_descriptions_in(expected).inspect}"
+        end
+
+      private
+
+        def match(_expected, actual)
+          return false unless actual.respond_to?(:[])
+
+          begin
+            return true if subsets_comparable? && subset_matches?
+            element_matches?
+          rescue ArgumentError
+            @actual_does_not_have_ordered_elements = true
+            return false
+          end
+        end
+
+        def subsets_comparable?
+          # Structs support the Enumerable interface but don't really have
+          # the semantics of a subset of a larger set...
+          return false if Struct === expected
+
+          expected.respond_to?(:length)
+        end
+      end
+
+      # For RSpec 3.1, the base class was named `StartAndEndWith`. For SemVer reasons,
+      # we still provide this constant until 4.0.
+      # @deprecated Use StartOrEndWith instead.
+      # @private
+      StartAndEndWith = StartOrEndWith
+
+      # @api private
+      # Provides the implementation for `start_with`.
+      # Not intended to be instantiated directly.
+      class StartWith < StartOrEndWith
+      private
+
+        def subset_matches?
+          values_match?(expected, actual[0, expected.length])
+        end
+
+        def element_matches?
+          values_match?(expected, actual[0])
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `end_with`.
+      # Not intended to be instantiated directly.
+      class EndWith < StartOrEndWith
+      private
+
+        def subset_matches?
+          values_match?(expected, actual[-expected.length, expected.length])
+        end
+
+        def element_matches?
+          values_match?(expected, actual[-1])
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/throw_symbol.rb b/rspec-expectations/lib/rspec/matchers/built_in/throw_symbol.rb
new file mode 100644
index 0000000..5131842
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/throw_symbol.rb
@@ -0,0 +1,132 @@
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @api private
+      # Provides the implementation for `throw_symbol`.
+      # Not intended to be instantiated directly.
+      class ThrowSymbol
+        include Composable
+
+        def initialize(expected_symbol=nil, expected_arg=nil)
+          @expected_symbol = expected_symbol
+          @expected_arg = expected_arg
+          @caught_symbol = @caught_arg = nil
+        end
+
+        # rubocop:disable MethodLength
+        # @private
+        def matches?(given_proc)
+          @block = given_proc
+          return false unless Proc === given_proc
+
+          begin
+            if @expected_symbol.nil?
+              given_proc.call
+            else
+              @caught_arg = catch :proc_did_not_throw_anything do
+                catch @expected_symbol do
+                  given_proc.call
+                  throw :proc_did_not_throw_anything, :nothing_thrown
+                end
+              end
+
+              if @caught_arg == :nothing_thrown
+                @caught_arg = nil
+              else
+                @caught_symbol = @expected_symbol
+              end
+            end
+
+            # Ruby 1.8 uses NameError with `symbol'
+            # Ruby 1.9 uses ArgumentError with :symbol
+          rescue NameError, ArgumentError => e
+            unless (match_data = e.message.match(/uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/))
+              other_exception = e
+              raise
+            end
+            @caught_symbol = match_data.captures[1].to_sym
+          rescue => other_exception
+            raise
+          ensure
+            # rubocop:disable EnsureReturn
+            unless other_exception
+              if @expected_symbol.nil?
+                return !!@caught_symbol
+              else
+                if @expected_arg.nil?
+                  return @caught_symbol == @expected_symbol
+                else
+                  return (@caught_symbol == @expected_symbol) && values_match?(@expected_arg, @caught_arg)
+                end
+              end
+            end
+            # rubocop:enable EnsureReturn
+          end
+        end
+        # rubocop:enable MethodLength
+
+        def does_not_match?(given_proc)
+          !matches?(given_proc) && Proc === given_proc
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          "expected #{expected} to be thrown, #{actual_result}"
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          "expected #{expected('no Symbol')}#{' not' if @expected_symbol} to be thrown, #{actual_result}"
+        end
+
+        # @api private
+        # @return [String]
+        def description
+          "throw #{expected}"
+        end
+
+        # @api private
+        # Indicates this matcher matches against a block.
+        # @return [True]
+        def supports_block_expectations?
+          true
+        end
+
+        def expects_call_stack_jump?
+          true
+        end
+
+      private
+
+        def actual_result
+          return "but was not a block" unless Proc === @block
+          "got #{caught}"
+        end
+
+        def expected(symbol_desc='a Symbol')
+          throw_description(@expected_symbol || symbol_desc, @expected_arg)
+        end
+
+        def caught
+          throw_description(@caught_symbol || 'nothing', @caught_arg)
+        end
+
+        def throw_description(symbol, arg)
+          symbol_description = symbol.is_a?(String) ? symbol : symbol.inspect
+
+          arg_description = if arg
+                              " with #{description_of arg}"
+                            elsif @expected_arg && @caught_symbol == @expected_symbol
+                              " with no argument"
+                            else
+                              ""
+                            end
+
+          symbol_description + arg_description
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/built_in/yield.rb b/rspec-expectations/lib/rspec/matchers/built_in/yield.rb
new file mode 100644
index 0000000..5bf991f
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/built_in/yield.rb
@@ -0,0 +1,416 @@
+RSpec::Support.require_rspec_support "method_signature_verifier"
+
+module RSpec
+  module Matchers
+    module BuiltIn
+      # @private
+      # Object that is yielded to `expect` when one of the
+      # yield matchers is used. Provides information about
+      # the yield behavior of the object-under-test.
+      class YieldProbe
+        def self.probe(block)
+          probe = new(block)
+          return probe unless probe.has_block?
+          probe.assert_valid_expect_block!
+          block.call(probe)
+          probe.assert_used!
+          probe
+        end
+
+        attr_accessor :num_yields, :yielded_args
+
+        def initialize(block)
+          @block = block
+          @used = false
+          self.num_yields, self.yielded_args = 0, []
+        end
+
+        def has_block?
+          Proc === @block
+        end
+
+        def to_proc
+          @used = true
+
+          probe = self
+          Proc.new do |*args|
+            probe.num_yields += 1
+            probe.yielded_args << args
+            nil # to indicate the block does not return a meaningful value
+          end
+        end
+
+        def single_yield_args
+          yielded_args.first
+        end
+
+        def yielded_once?(matcher_name)
+          case num_yields
+          when 1 then true
+          when 0 then false
+          else
+            raise "The #{matcher_name} matcher is not designed to be used with a " \
+                  "method that yields multiple times. Use the yield_successive_args " \
+                  "matcher for that case."
+          end
+        end
+
+        def successive_yield_args
+          yielded_args.map do |arg_array|
+            arg_array.size == 1 ? arg_array.first : arg_array
+          end
+        end
+
+        def assert_used!
+          return if @used
+          raise "You must pass the argument yielded to your expect block on " \
+                "to the method-under-test as a block. It acts as a probe that " \
+                "allows the matcher to detect whether or not the method-under-test " \
+                "yields, and, if so, how many times, and what the yielded arguments " \
+                "are."
+        end
+
+        if RUBY_VERSION.to_f > 1.8
+          def assert_valid_expect_block!
+            block_signature = RSpec::Support::BlockSignature.new(@block)
+            return if RSpec::Support::StrictSignatureVerifier.new(block_signature, [self]).valid?
+            raise "Your expect block must accept an argument to be used with this " \
+                  "matcher. Pass the argument as a block on to the method you are testing."
+          end
+        else
+          # On 1.8.7, `lambda { }.arity` and `lambda { |*a| }.arity` both return -1,
+          # so we can't distinguish between accepting no args and an arg splat.
+          # It's OK to skip, this, though; it just provides a nice error message
+          # when the user forgets to accept an arg in their block. They'll still get
+          # the `assert_used!` error message from above, which is sufficient.
+          def assert_valid_expect_block!
+            # nothing to do
+          end
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `yield_control`.
+      # Not intended to be instantiated directly.
+      class YieldControl < BaseMatcher
+        def initialize
+          at_least(:once)
+        end
+
+        # @api public
+        # Specifies that the method is expected to yield once.
+        def once
+          exactly(1)
+          self
+        end
+
+        # @api public
+        # Specifies that the method is expected to yield twice.
+        def twice
+          exactly(2)
+          self
+        end
+
+        # @api public
+        # Specifies that the method is expected to yield thrice.
+        def thrice
+          exactly(3)
+          self
+        end
+
+        # @api public
+        # Specifies that the method is expected to yield the given number of times.
+        def exactly(number)
+          set_expected_yields_count(:==, number)
+          self
+        end
+
+        # @api public
+        # Specifies the maximum number of times the method is expected to yield
+        def at_most(number)
+          set_expected_yields_count(:<=, number)
+          self
+        end
+
+        # @api public
+        # Specifies the minimum number of times the method is expected to yield
+        def at_least(number)
+          set_expected_yields_count(:>=, number)
+          self
+        end
+
+        # @api public
+        # No-op. Provides syntactic sugar.
+        def times
+          self
+        end
+
+        # @private
+        def matches?(block)
+          @probe = YieldProbe.probe(block)
+          return false unless @probe.has_block?
+
+          @probe.num_yields.__send__(@expectation_type, @expected_yields_count)
+        end
+
+        # @private
+        def does_not_match?(block)
+          !matches?(block) && @probe.has_block?
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message
+          'expected given block to yield control' + failure_reason
+        end
+
+        # @api private
+        # @return [String]
+        def failure_message_when_negated
+          'expected given block not to yield control' + failure_reason
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def set_expected_yields_count(relativity, n)
+          @expectation_type = relativity
+          @expected_yields_count = case n
+                                   when Numeric then n
+                                   when :once then 1
+                                   when :twice then 2
+                                   when :thrice then 3
+                                   end
+        end
+
+        def failure_reason
+          return " but was not a block" unless @probe.has_block?
+          return '' unless @expected_yields_count
+          " #{human_readable_expectation_type}#{human_readable_count(@expected_yields_count)}" \
+          " but yielded #{human_readable_count(@probe.num_yields)}"
+        end
+
+        def human_readable_expectation_type
+          case @expectation_type
+          when :<= then 'at most '
+          when :>= then 'at least '
+          else ''
+          end
+        end
+
+        def human_readable_count(count)
+          case count
+          when 1 then "once"
+          when 2 then "twice"
+          else "#{count} times"
+          end
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `yield_with_no_args`.
+      # Not intended to be instantiated directly.
+      class YieldWithNoArgs < BaseMatcher
+        # @private
+        def matches?(block)
+          @probe = YieldProbe.probe(block)
+          return false unless @probe.has_block?
+          @probe.yielded_once?(:yield_with_no_args) && @probe.single_yield_args.empty?
+        end
+
+        # @private
+        def does_not_match?(block)
+          !matches?(block) && @probe.has_block?
+        end
+
+        # @private
+        def failure_message
+          "expected given block to yield with no arguments, but #{positive_failure_reason}"
+        end
+
+        # @private
+        def failure_message_when_negated
+          "expected given block not to yield with no arguments, but #{negative_failure_reason}"
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def positive_failure_reason
+          return "was not a block" unless @probe.has_block?
+          return "did not yield" if @probe.num_yields.zero?
+          "yielded with arguments: #{@probe.single_yield_args.inspect}"
+        end
+
+        def negative_failure_reason
+          return "was not a block" unless @probe.has_block?
+          "did"
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `yield_with_args`.
+      # Not intended to be instantiated directly.
+      class YieldWithArgs < BaseMatcher
+        def initialize(*args)
+          @expected = args
+        end
+
+        # @private
+        def matches?(block)
+          @probe = YieldProbe.probe(block)
+          return false unless @probe.has_block?
+          @actual = @probe.single_yield_args
+          @probe.yielded_once?(:yield_with_args) && args_match?
+        end
+
+        # @private
+        def does_not_match?(block)
+          !matches?(block) && @probe.has_block?
+        end
+
+        # @private
+        def failure_message
+          "expected given block to yield with arguments, but #{positive_failure_reason}"
+        end
+
+        # @private
+        def failure_message_when_negated
+          "expected given block not to yield with arguments, but #{negative_failure_reason}"
+        end
+
+        # @private
+        def description
+          desc = "yield with args"
+          desc << "(#{expected_arg_description})" unless @expected.empty?
+          desc
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def positive_failure_reason
+          return "was not a block" unless @probe.has_block?
+          return "did not yield" if @probe.num_yields.zero?
+          @positive_args_failure
+        end
+
+        def expected_arg_description
+          @expected.map { |e| description_of e }.join(", ")
+        end
+
+        def negative_failure_reason
+          if !@probe.has_block?
+            "was not a block"
+          elsif all_args_match?
+            "yielded with expected arguments" \
+              "\nexpected not: #{surface_descriptions_in(@expected).inspect}" +
+              "\n         got: #{@actual.inspect}"
+          else
+            "did"
+          end
+        end
+
+        def args_match?
+          if @expected.empty? # expect {...}.to yield_with_args
+            @positive_args_failure = "yielded with no arguments" if @actual.empty?
+            return !@actual.empty?
+          end
+
+          unless (match = all_args_match?)
+            @positive_args_failure = "yielded with unexpected arguments" \
+              "\nexpected: #{surface_descriptions_in(@expected).inspect}" +
+              "\n     got: #{@actual.inspect}"
+          end
+
+          match
+        end
+
+        def all_args_match?
+          values_match?(@expected, @actual)
+        end
+      end
+
+      # @api private
+      # Provides the implementation for `yield_successive_args`.
+      # Not intended to be instantiated directly.
+      class YieldSuccessiveArgs < BaseMatcher
+        def initialize(*args)
+          @expected = args
+        end
+
+        # @private
+        def matches?(block)
+          @probe = YieldProbe.probe(block)
+          return false unless @probe.has_block?
+          @actual = @probe.successive_yield_args
+          args_match?
+        end
+
+        def does_not_match?(block)
+          !matches?(block) && @probe.has_block?
+        end
+
+        # @private
+        def failure_message
+          "expected given block to yield successively with arguments, but #{positive_failure_reason}"
+        end
+
+        # @private
+        def failure_message_when_negated
+          "expected given block not to yield successively with arguments, but #{negative_failure_reason}"
+        end
+
+        # @private
+        def description
+          desc = "yield successive args"
+          desc << "(#{expected_arg_description})"
+          desc
+        end
+
+        # @private
+        def supports_block_expectations?
+          true
+        end
+
+      private
+
+        def args_match?
+          values_match?(@expected, @actual)
+        end
+
+        def expected_arg_description
+          @expected.map { |e| description_of e }.join(", ")
+        end
+
+        def positive_failure_reason
+          return "was not a block" unless @probe.has_block?
+
+          "yielded with unexpected arguments" \
+          "\nexpected: #{surface_descriptions_in(@expected).inspect}" \
+          "\n     got: #{@actual.inspect}"
+        end
+
+        def negative_failure_reason
+          return "was not a block" unless @probe.has_block?
+
+          "yielded with expected arguments" \
+          "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \
+          "\n         got: #{@actual.inspect}"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/composable.rb b/rspec-expectations/lib/rspec/matchers/composable.rb
new file mode 100644
index 0000000..81e65e9
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/composable.rb
@@ -0,0 +1,183 @@
+RSpec::Support.require_rspec_support "fuzzy_matcher"
+
+module RSpec
+  module Matchers
+    # Mixin designed to support the composable matcher features
+    # of RSpec 3+. Mix it into your custom matcher classes to
+    # allow them to be used in a composable fashion.
+    #
+    # @api public
+    module Composable
+      # Creates a compound `and` expectation. The matcher will
+      # only pass if both sub-matchers pass.
+      # This can be chained together to form an arbitrarily long
+      # chain of matchers.
+      #
+      # @example
+      #   expect(alphabet).to start_with("a").and end_with("z")
+      #   expect(alphabet).to start_with("a") & end_with("z")
+      #
+      # @note The negative form (`expect(...).not_to matcher.and other`)
+      #   is not supported at this time.
+      def and(matcher)
+        BuiltIn::Compound::And.new self, matcher
+      end
+      alias & and
+
+      # Creates a compound `or` expectation. The matcher will
+      # pass if either sub-matcher passes.
+      # This can be chained together to form an arbitrarily long
+      # chain of matchers.
+      #
+      # @example
+      #   expect(stoplight.color).to eq("red").or eq("green").or eq("yellow")
+      #   expect(stoplight.color).to eq("red") | eq("green") | eq("yellow")
+      #
+      # @note The negative form (`expect(...).not_to matcher.or other`)
+      #   is not supported at this time.
+      def or(matcher)
+        BuiltIn::Compound::Or.new self, matcher
+      end
+      alias | or
+
+      # Delegates to `#matches?`. Allows matchers to be used in composable
+      # fashion and also supports using matchers in case statements.
+      def ===(value)
+        matches?(value)
+      end
+
+    private
+
+      # This provides a generic way to fuzzy-match an expected value against
+      # an actual value. It understands nested data structures (e.g. hashes
+      # and arrays) and is able to match against a matcher being used as
+      # the expected value or within the expected value at any level of
+      # nesting.
+      #
+      # Within a custom matcher you are encouraged to use this whenever your
+      # matcher needs to match two values, unless it needs more precise semantics.
+      # For example, the `eq` matcher _does not_ use this as it is meant to
+      # use `==` (and only `==`) for matching.
+      #
+      # @param expected [Object] what is expected
+      # @param actual [Object] the actual value
+      #
+      # @!visibility public
+      def values_match?(expected, actual)
+        expected = with_matchers_cloned(expected)
+        Support::FuzzyMatcher.values_match?(expected, actual)
+      end
+
+      # Returns the description of the given object in a way that is
+      # aware of composed matchers. If the object is a matcher with
+      # a `description` method, returns the description; otherwise
+      # returns `object.inspect`.
+      #
+      # You are encouraged to use this in your custom matcher's
+      # `description`, `failure_message` or
+      # `failure_message_when_negated` implementation if you are
+      # supporting matcher arguments.
+      #
+      # @!visibility public
+      def description_of(object)
+        return object.description if Matchers.is_a_describable_matcher?(object)
+        object.inspect
+      end
+
+      # Transforms the given data structue (typically a hash or array)
+      # into a new data structure that, when `#inspect` is called on it,
+      # will provide descriptions of any contained matchers rather than
+      # the normal `#inspect` output.
+      #
+      # You are encouraged to use this in your custom matcher's
+      # `description`, `failure_message` or
+      # `failure_message_when_negated` implementation if you are
+      # supporting any arguments which may be a data structure
+      # containing matchers.
+      #
+      # @!visibility public
+      def surface_descriptions_in(item)
+        if Matchers.is_a_describable_matcher?(item)
+          DescribableItem.new(item)
+        elsif Hash === item
+          Hash[surface_descriptions_in(item.to_a)]
+        elsif Struct === item
+          item.inspect
+        elsif enumerable?(item)
+          begin
+            item.map { |subitem| surface_descriptions_in(subitem) }
+          rescue IOError # STDOUT is enumerable but `map` raises an error
+            item.inspect
+          end
+        else
+          item
+        end
+      end
+
+      # @private
+      # Historically, a single matcher instance was only checked
+      # against a single value. Given that the matcher was only
+      # used once, it's been common to memoize some intermediate
+      # calculation that is derived from the `actual` value in
+      # order to reuse that intermediate result in the failure
+      # message.
+      #
+      # This can cause a problem when using such a matcher as an
+      # argument to another matcher in a composed matcher expression,
+      # since the matcher instance may be checked against multiple
+      # values and produce invalid results due to the memoization.
+      #
+      # To deal with this, we clone any matchers in `expected` via
+      # this method when using `values_match?`, so that any memoization
+      # does not "leak" between checks.
+      def with_matchers_cloned(object)
+        if Matchers.is_a_matcher?(object)
+          object.clone
+        elsif Hash === object
+          Hash[with_matchers_cloned(object.to_a)]
+        elsif Struct === object
+          object
+        elsif enumerable?(object)
+          begin
+            object.map { |subobject| with_matchers_cloned(subobject) }
+          rescue IOError # STDOUT is enumerable but `map` raises an error
+            object
+          end
+        else
+          object
+        end
+      end
+
+      if String.ancestors.include?(Enumerable) # 1.8.7
+        # Strings are not enumerable on 1.9, and on 1.8 they are an infinitely
+        # nested enumerable: since ruby lacks a character class, it yields
+        # 1-character strings, which are themselves enumerable, composed of a
+        # a single 1-character string, which is an enumerable, etc.
+        #
+        # @api private
+        def enumerable?(item)
+          return false if String === item
+          Enumerable === item
+        end
+      else
+        # @api private
+        def enumerable?(item)
+          Enumerable === item
+        end
+      end
+      module_function :surface_descriptions_in, :enumerable?
+
+      # Wraps an item in order to surface its `description` via `inspect`.
+      # @api private
+      DescribableItem = Struct.new(:item) do
+        def inspect
+          "(#{item.description})"
+        end
+
+        def pretty_print(pp)
+          pp.text "(#{item.description})"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/dsl.rb b/rspec-expectations/lib/rspec/matchers/dsl.rb
new file mode 100644
index 0000000..702f05d
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/dsl.rb
@@ -0,0 +1,440 @@
+module RSpec
+  module Matchers
+    # Defines the custom matcher DSL.
+    module DSL
+      # Defines a custom matcher.
+      # @see RSpec::Matchers
+      def define(name, &declarations)
+        warn_about_block_args(name, declarations)
+        define_method name do |*expected, &block_arg|
+          RSpec::Matchers::DSL::Matcher.new(name, declarations, self, *expected, &block_arg)
+        end
+      end
+      alias_method :matcher, :define
+
+    private
+
+      if Proc.method_defined?(:parameters)
+        def warn_about_block_args(name, declarations)
+          declarations.parameters.each do |type, arg_name|
+            next unless type == :block
+            RSpec.warning("Your `#{name}` custom matcher receives a block argument (`#{arg_name}`), " \
+                          "but due to limitations in ruby, RSpec cannot provide the block. Instead, " \
+                          "use the `block_arg` method to access the block")
+          end
+        end
+      else
+        def warn_about_block_args(*)
+          # There's no way to detect block params on 1.8 since the method reflection APIs don't expose it
+        end
+      end
+
+      RSpec.configure { |c| c.extend self } if RSpec.respond_to?(:configure)
+
+      # Contains the methods that are available from within the
+      # `RSpec::Matchers.define` DSL for creating custom matchers.
+      module Macros
+        # Stores the block that is used to determine whether this matcher passes
+        # or fails. The block should return a boolean value. When the matcher is
+        # passed to `expect(...).to` and the block returns `true`, then the expectation
+        # passes. Similarly, when the matcher is passed to `expect(...).not_to` and the
+        # block returns `false`, then the expectation passes.
+        #
+        # @example
+        #
+        #     RSpec::Matchers.define :be_even do
+        #       match do |actual|
+        #         actual.even?
+        #       end
+        #     end
+        #
+        #     expect(4).to be_even     # passes
+        #     expect(3).not_to be_even # passes
+        #     expect(3).to be_even     # fails
+        #     expect(4).not_to be_even # fails
+        #
+        # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`)
+        def match(&match_block)
+          define_user_override(:matches?, match_block) do |actual|
+            begin
+              @actual = actual
+              super(*actual_arg_for(match_block))
+            rescue RSpec::Expectations::ExpectationNotMetError
+              false
+            end
+          end
+        end
+
+        # Use this to define the block for a negative expectation (`expect(...).not_to`)
+        # when the positive and negative forms require different handling. This
+        # is rarely necessary, but can be helpful, for example, when specifying
+        # asynchronous processes that require different timeouts.
+        #
+        # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`)
+        def match_when_negated(&match_block)
+          define_user_override(:does_not_match?, match_block) do |actual|
+            @actual = actual
+            super(*actual_arg_for(match_block))
+          end
+        end
+
+        # Use this instead of `match` when the block will raise an exception
+        # rather than returning false to indicate a failure.
+        #
+        # @example
+        #
+        #     RSpec::Matchers.define :accept_as_valid do |candidate_address|
+        #       match_unless_raises ValidationException do |validator|
+        #         validator.validate(candidate_address)
+        #       end
+        #     end
+        #
+        #     expect(email_validator).to accept_as_valid("person at company.com")
+        #
+        # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`)
+        def match_unless_raises(expected_exception=Exception, &match_block)
+          define_user_override(:matches?, match_block) do |actual|
+            @actual = actual
+            begin
+              super(*actual_arg_for(match_block))
+            rescue expected_exception => @rescued_exception
+              false
+            else
+              true
+            end
+          end
+        end
+
+        # Customizes the failure messsage to use when this matcher is
+        # asked to positively match. Only use this when the message
+        # generated by default doesn't suit your needs.
+        #
+        # @example
+        #
+        #     RSpec::Matchers.define :have_strength do |expected|
+        #       match { your_match_logic }
+        #
+        #       failure_message do |actual|
+        #         "Expected strength of #{expected}, but had #{actual.strength}"
+        #       end
+        #     end
+        #
+        # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`)
+        def failure_message(&definition)
+          define_user_override(__method__, definition)
+        end
+
+        # Customize the failure messsage to use when this matcher is asked
+        # to negatively match. Only use this when the message generated by
+        # default doesn't suit your needs.
+        #
+        # @example
+        #
+        #     RSpec::Matchers.define :have_strength do |expected|
+        #       match { your_match_logic }
+        #
+        #       failure_message_when_negated do |actual|
+        #         "Expected not to have strength of #{expected}, but did"
+        #       end
+        #     end
+        #
+        # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`)
+        def failure_message_when_negated(&definition)
+          define_user_override(__method__, definition)
+        end
+
+        # Customize the description to use for one-liners.  Only use this when
+        # the description generated by default doesn't suit your needs.
+        #
+        # @example
+        #
+        #     RSpec::Matchers.define :qualify_for do |expected|
+        #       match { your_match_logic }
+        #
+        #       description do
+        #         "qualify for #{expected}"
+        #       end
+        #     end
+        #
+        # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`)
+        def description(&definition)
+          define_user_override(__method__, definition)
+        end
+
+        # Tells the matcher to diff the actual and expected values in the failure
+        # message.
+        def diffable
+          define_method(:diffable?) { true }
+        end
+
+        # Declares that the matcher can be used in a block expectation.
+        # Users will not be able to use your matcher in a block
+        # expectation without declaring this.
+        # (e.g. `expect { do_something }.to matcher`).
+        def supports_block_expectations
+          define_method(:supports_block_expectations?) { true }
+        end
+
+        # Convenience for defining methods on this matcher to create a fluent
+        # interface. The trick about fluent interfaces is that each method must
+        # return self in order to chain methods together. `chain` handles that
+        # for you. If the method is invoked and the
+        # `include_chain_clauses_in_custom_matcher_descriptions` config option
+        # hash been enabled, the chained method name and args will be added to the
+        # default description and failure message.
+        #
+        # In the common case where you just want the chained method to store some
+        # value(s) for later use (e.g. in `match`), you can provide one or more
+        # attribute names instead of a block; the chained method will store its
+        # arguments in instance variables with those names, and the values will
+        # be exposed via getters.
+        #
+        # @example
+        #
+        #     RSpec::Matchers.define :have_errors_on do |key|
+        #       chain :with do |message|
+        #         @message = message
+        #       end
+        #
+        #       match do |actual|
+        #         actual.errors[key] == @message
+        #       end
+        #     end
+        #
+        #     expect(minor).to have_errors_on(:age).with("Not old enough to participate")
+        def chain(method_name, *attr_names, &definition)
+          unless block_given? ^ attr_names.any?
+            raise ArgumentError, "You must pass either a block or some attribute names (but not both) to `chain`."
+          end
+
+          definition = assign_attributes(attr_names) if attr_names.any?
+
+          define_user_override(method_name, definition) do |*args, &block|
+            super(*args, &block)
+            @chained_method_clauses.push([method_name, args])
+            self
+          end
+        end
+
+        def assign_attributes(attr_names)
+          attr_reader(*attr_names)
+          private(*attr_names)
+
+          lambda do |*attr_values|
+            attr_names.zip(attr_values) do |attr_name, attr_value|
+              instance_variable_set(:"@#{attr_name}", attr_value)
+            end
+          end
+        end
+
+        # assign_attributes isn't defined in the private section below because
+        # that makes MRI 1.9.2 emit a warning about private attributes.
+        private :assign_attributes
+
+      private
+
+        # Does the following:
+        #
+        # - Defines the named method using a user-provided block
+        #   in @user_method_defs, which is included as an ancestor
+        #   in the singleton class in which we eval the `define` block.
+        # - Defines an overriden definition for the same method
+        #   usign the provided `our_def` block.
+        # - Provides a default `our_def` block for the common case
+        #   of needing to call the user's definition with `@actual`
+        #   as an arg, but only if their block's arity can handle it.
+        #
+        # This compiles the user block into an actual method, allowing
+        # them to use normal method constructs like `return`
+        # (e.g. for a early guard statement), while allowing us to define
+        # an override that can provide the wrapped handling
+        # (e.g. assigning `@actual`, rescueing errors, etc) and
+        # can `super` to the user's definition.
+        def define_user_override(method_name, user_def, &our_def)
+          @user_method_defs.__send__(:define_method, method_name, &user_def)
+          our_def ||= lambda { super(*actual_arg_for(user_def)) }
+          define_method(method_name, &our_def)
+        end
+
+        # Defines deprecated macro methods from RSpec 2 for backwards compatibility.
+        # @deprecated Use the methods from {Macros} instead.
+        module Deprecated
+          # @deprecated Use {Macros#match} instead.
+          def match_for_should(&definition)
+            RSpec.deprecate("`match_for_should`", :replacement => "`match`")
+            match(&definition)
+          end
+
+          # @deprecated Use {Macros#match_when_negated} instead.
+          def match_for_should_not(&definition)
+            RSpec.deprecate("`match_for_should_not`", :replacement => "`match_when_negated`")
+            match_when_negated(&definition)
+          end
+
+          # @deprecated Use {Macros#failure_message} instead.
+          def failure_message_for_should(&definition)
+            RSpec.deprecate("`failure_message_for_should`", :replacement => "`failure_message`")
+            failure_message(&definition)
+          end
+
+          # @deprecated Use {Macros#failure_message_when_negated} instead.
+          def failure_message_for_should_not(&definition)
+            RSpec.deprecate("`failure_message_for_should_not`", :replacement => "`failure_message_when_negated`")
+            failure_message_when_negated(&definition)
+          end
+        end
+      end
+
+      # Defines default implementations of the matcher
+      # protocol methods for custom matchers. You can
+      # override any of these using the {RSpec::Matchers::DSL::Macros Macros} methods
+      # from within an `RSpec::Matchers.define` block.
+      module DefaultImplementations
+        include BuiltIn::BaseMatcher::DefaultFailureMessages
+
+        # @api private
+        # Used internally by objects returns by `should` and `should_not`.
+        def diffable?
+          false
+        end
+
+        # The default description.
+        def description
+          "#{name_to_sentence}#{to_sentence expected}#{chained_method_clause_sentences}"
+        end
+
+        # Matchers do not support block expectations by default. You
+        # must opt-in.
+        def supports_block_expectations?
+          false
+        end
+
+        # Most matchers do not expect call stack jumps.
+        def expects_call_stack_jump?
+          false
+        end
+
+      private
+
+        def chained_method_clause_sentences
+          return '' unless Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions?
+
+          @chained_method_clauses.map do |(method_name, method_args)|
+            " #{split_words(method_name)}#{to_sentence(method_args)}"
+          end.join
+        end
+      end
+
+      # The class used for custom matchers. The block passed to
+      # `RSpec::Matchers.define` will be evaluated in the context
+      # of the singleton class of an instance, and will have the
+      # {RSpec::Matchers::DSL::Macros Macros} methods available.
+      class Matcher
+        # Provides default implementations for the matcher protocol methods.
+        include DefaultImplementations
+
+        # Allows expectation expressions to be used in the match block.
+        include RSpec::Matchers
+
+        # Converts matcher name and expected args to an English expresion.
+        include RSpec::Matchers::Pretty
+
+        # Supports the matcher composability features of RSpec 3+.
+        include Composable
+
+        # Makes the macro methods available to an `RSpec::Matchers.define` block.
+        extend Macros
+        extend Macros::Deprecated
+
+        # Exposes the value being matched against -- generally the object
+        # object wrapped by `expect`.
+        attr_reader :actual
+
+        # Exposes the exception raised during the matching by `match_unless_raises`.
+        # Could be useful to extract details for a failure message.
+        attr_reader :rescued_exception
+
+        # The block parameter used in the expectation
+        attr_reader :block_arg
+
+        # @api private
+        def initialize(name, declarations, matcher_execution_context, *expected, &block_arg)
+          @name     = name
+          @actual   = nil
+          @expected_as_array = expected
+          @matcher_execution_context = matcher_execution_context
+          @chained_method_clauses = []
+          @block_arg = block_arg
+
+          class << self
+            # See `Macros#define_user_override` above, for an explanation.
+            include(@user_method_defs = Module.new)
+            self
+          end.class_exec(*expected, &declarations)
+        end
+
+        # Provides the expected value. This will return an array if
+        # multiple arguments were passed to the matcher; otherwise it
+        # will return a single value.
+        # @see #expected_as_array
+        def expected
+          if expected_as_array.size == 1
+            expected_as_array[0]
+          else
+            expected_as_array
+          end
+        end
+
+        # Returns the expected value as an an array. This exists primarily
+        # to aid in upgrading from RSpec 2.x, since in RSpec 2, `expected`
+        # always returned an array.
+        # @see #expected
+        attr_reader :expected_as_array
+
+        # Adds the name (rather than a cryptic hex number)
+        # so we can identify an instance of
+        # the matcher in error messages (e.g. for `NoMethodError`)
+        def inspect
+          "#<#{self.class.name} #{name}>"
+        end
+
+        if RUBY_VERSION.to_f >= 1.9
+          # Indicates that this matcher responds to messages
+          # from the `@matcher_execution_context` as well.
+          # Also, supports getting a method object for such methods.
+          def respond_to_missing?(method, include_private=false)
+            super || @matcher_execution_context.respond_to?(method, include_private)
+          end
+        else # for 1.8.7
+          # Indicates that this matcher responds to messages
+          # from the `@matcher_execution_context` as well.
+          def respond_to?(method, include_private=false)
+            super || @matcher_execution_context.respond_to?(method, include_private)
+          end
+        end
+
+      private
+
+        def actual_arg_for(block)
+          block.arity.zero? ? [] : [@actual]
+        end
+
+        # Takes care of forwarding unhandled messages to the
+        # `@matcher_execution_context` (typically the current
+        # running `RSpec::Core::Example`). This is needed by
+        # rspec-rails so that it can define matchers that wrap
+        # Rails' test helper methods, but it's also a useful
+        # feature in its own right.
+        def method_missing(method, *args, &block)
+          if @matcher_execution_context.respond_to?(method)
+            @matcher_execution_context.__send__ method, *args, &block
+          else
+            super(method, *args, &block)
+          end
+        end
+      end
+    end
+  end
+end
+
+RSpec::Matchers.extend RSpec::Matchers::DSL
diff --git a/rspec-expectations/lib/rspec/matchers/expecteds_for_multiple_diffs.rb b/rspec-expectations/lib/rspec/matchers/expecteds_for_multiple_diffs.rb
new file mode 100644
index 0000000..2a38b4e
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/expecteds_for_multiple_diffs.rb
@@ -0,0 +1,79 @@
+module RSpec
+  module Matchers
+    # @api private
+    # Handles list of expected values when there is a need to render
+    # multiple diffs. Also can handle one value.
+    class ExpectedsForMultipleDiffs
+      # @private
+      # Default diff label when there is only one matcher in diff
+      # output
+      DEFAULT_DIFF_LABEL = "Diff:".freeze
+
+      # @private
+      # Maximum readable matcher description length
+      DESCRIPTION_MAX_LENGTH = 65
+
+      def initialize(expected_list)
+        @expected_list = expected_list
+      end
+
+      # @api private
+      # Wraps provided expected value in instance of
+      # ExpectedForMultipleDiffs. If provided value is already an
+      # ExpectedForMultipleDiffs then it just returns it.
+      # @param [Any] expected value to be wrapped
+      # @return [RSpec::Matchers::ExpectedsForMultipleDiffs]
+      def self.from(expected)
+        return expected if self === expected
+        new([[expected, DEFAULT_DIFF_LABEL]])
+      end
+
+      # @api private
+      # Wraps provided matcher list in instance of
+      # ExpectedForMultipleDiffs.
+      # @param [Array<Any>] matchers list of matchers to wrap
+      # @return [RSpec::Matchers::ExpectedsForMultipleDiffs]
+      def self.for_many_matchers(matchers)
+        new(matchers.map { |m| [m.expected, diff_label_for(m)] })
+      end
+
+      # @api private
+      # Returns message with diff(s) appended for provided differ
+      # factory and actual value if there are any
+      # @param [String] message original failure message
+      # @param [Proc] differ
+      # @param [Any] actual value
+      # @return [String]
+      def message_with_diff(message, differ, actual)
+        diff = diffs(differ, actual)
+        message = "#{message}\n#{diff}" unless diff.empty?
+        message
+      end
+
+    private
+
+      def self.diff_label_for(matcher)
+        "Diff for (#{truncated(description_for(matcher))}):"
+      end
+
+      def self.description_for(matcher)
+        matcher.description
+      rescue NoMethodError
+        matcher.inspect
+      end
+
+      def self.truncated(description)
+        return description if description.length <= DESCRIPTION_MAX_LENGTH
+        description[0...DESCRIPTION_MAX_LENGTH - 3] << "..."
+      end
+
+      def diffs(differ, actual)
+        @expected_list.map do |(expected, diff_label)|
+          diff = differ.diff(actual, expected)
+          next if diff.empty?
+          "#{diff_label}#{diff}"
+        end.compact.join("\n")
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/generated_descriptions.rb b/rspec-expectations/lib/rspec/matchers/generated_descriptions.rb
new file mode 100644
index 0000000..a17ce18
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/generated_descriptions.rb
@@ -0,0 +1,42 @@
+module RSpec
+  module Matchers
+    class << self
+      # @private
+      attr_accessor :last_matcher, :last_expectation_handler
+    end
+
+    # @api private
+    # Used by rspec-core to clear the state used to generate
+    # descriptions after an example.
+    def self.clear_generated_description
+      self.last_matcher = nil
+      self.last_expectation_handler = nil
+    end
+
+    # @api private
+    # Generates an an example description based on the last expectation.
+    # Used by rspec-core's one-liner syntax.
+    def self.generated_description
+      return nil if last_expectation_handler.nil?
+      "#{last_expectation_handler.verb} #{last_description}"
+    end
+
+  private
+
+    def self.last_description
+      last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE
+When you call a matcher in an example without a String, like this:
+
+specify { expect(object).to matcher }
+
+or this:
+
+it { is_expected.to matcher }
+
+RSpec expects the matcher to have a #description method. You should either
+add a String to the example this matcher is being used in, or give it a
+description method. Then you won't have to suffer this lengthy warning again.
+MESSAGE
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/matcher_delegator.rb b/rspec-expectations/lib/rspec/matchers/matcher_delegator.rb
new file mode 100644
index 0000000..9dd3b18
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/matcher_delegator.rb
@@ -0,0 +1,33 @@
+module RSpec
+  module Matchers
+    # Provides the necessary plumbing to wrap a matcher with a decorator.
+    # @private
+    class MatcherDelegator
+      include Composable
+      attr_reader :base_matcher
+
+      def initialize(base_matcher)
+        @base_matcher = base_matcher
+      end
+
+      def method_missing(*args, &block)
+        base_matcher.__send__(*args, &block)
+      end
+
+      if ::RUBY_VERSION.to_f > 1.8
+        def respond_to_missing?(name, include_all=false)
+          super || base_matcher.respond_to?(name, include_all)
+        end
+      else
+        def respond_to?(name, include_all=false)
+          super || base_matcher.respond_to?(name, include_all)
+        end
+      end
+
+      def initialize_copy(other)
+        @base_matcher = @base_matcher.clone
+        super
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/matcher_protocol.rb b/rspec-expectations/lib/rspec/matchers/matcher_protocol.rb
new file mode 100644
index 0000000..c5bc432
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/matcher_protocol.rb
@@ -0,0 +1,99 @@
+module RSpec
+  module Matchers
+    # rspec-expectations can work with any matcher object that implements this protocol.
+    #
+    # @note This class is not loaded at runtime by rspec-expectations. It exists
+    #   purely to provide documentation for the matcher protocol.
+    class MatcherProtocol
+      # @!group Required Methods
+
+      # @!method matches?(actual)
+      #   @param actual [Object] The object being matched against.
+      #   @yield For an expression like `expect(x).to matcher do...end`, the `do/end`
+      #     block binds to `to`. It passes that block, if there is one, on to this method.
+      #   @return [Boolean] true if this matcher matches the provided object.
+
+      # @!method failure_message
+      #   This will only be called if {#matches?} returns false.
+      #   @return [String] Explanation for the failure.
+
+      # @!endgroup
+
+      # @!group Optional Methods
+
+      # @!method does_not_match?(actual)
+      #   In a negative expectation such as `expect(x).not_to foo`, RSpec will
+      #   call `foo.does_not_match?(x)` if this method is defined. If it's not
+      #   defined it will fall back to using `!foo.matches?(x)`. This allows you
+      #   to provide custom logic for the negative case.
+      #
+      #   @param actual [Object] The object being matched against.
+      #   @yield For an expression like `expect(x).not_to matcher do...end`, the `do/end`
+      #     block binds to `not_to`. It passes that block, if there is one, on to this method.
+      #   @return [Boolean] true if this matcher does not match the provided object.
+
+      # @!method failure_message_when_negated
+      #   This will only be called when a negative match fails.
+      #   @return [String] Explanation for the failure.
+      #   @note This method is listed as optional because matchers do not have to
+      #     support negation. But if your matcher does support negation, this is a
+      #     required method -- otherwise, you'll get a `NoMethodError`.
+
+      # @!method description
+      #   The description is used for two things:
+      #
+      #     * When using RSpec's one-liner syntax
+      #       (e.g. `it { is_expected.to matcher }`), the description
+      #       is used to generate the example's doc string since you
+      #       have not provided one.
+      #     * In a composed matcher expression, the description is used
+      #       as part of the failure message (and description) of the outer
+      #       matcher.
+      #
+      #   @return [String] Description of the matcher.
+
+      # @!method supports_block_expectations?
+      #   Indicates that this matcher can be used in a block expectation expression,
+      #   such as `expect { foo }.to raise_error`. Generally speaking, this is
+      #   only needed for matchers which operate on a side effect of a block, rather
+      #   than on a particular object.
+      #   @return [Boolean] true if this matcher can be used in block expressions.
+      #   @note If not defined, RSpec assumes a value of `false` for this method.
+
+      # @!method expects_call_stack_jump?
+      #   Indicates that when this matcher is used in a block expectation
+      #   expression, it expects the block to use a ruby construct that causes
+      #   a call stack jump (such as raising an error or throwing a symbol).
+      #
+      #   This is used internally for compound block expressions, as matchers
+      #   which expect call stack jumps must be treated with care to work properly.
+      #
+      #   @return [Boolean] true if the matcher expects a call stack jump
+      #
+      #   @note This method is very rarely used or needed.
+      #   @note If not defined, RSpec assumes a value of `false` for this method.
+
+      # @!method diffable?
+      #   @return [Boolean] true if `actual` and `expected` can be diffed.
+      #   Indicates that this matcher provides `actual` and `expected` attributes,
+      #   and that the values returned by these can be usefully diffed, which can
+      #   be included in the output.
+
+      # @!method actual
+      #   @return [String, Object] If an object (rather than a string) is provided,
+      #     RSpec will use the `pp` library to convert it to multi-line output in
+      #     order to diff.
+      #   The actual value for the purposes of a diff.
+      #   @note This method is required if `diffable?` returns true.
+
+      # @!method expected
+      #   @return [String, Object] If an object (rather than a string) is provided,
+      #     RSpec will use the `pp` library to convert it to multi-line output in
+      #     order to diff.
+      #   The expected value for the purposes of a diff.
+      #   @note This method is required if `diffable?` returns true.
+
+      # @!endgroup
+    end
+  end
+end
diff --git a/rspec-expectations/lib/rspec/matchers/pretty.rb b/rspec-expectations/lib/rspec/matchers/pretty.rb
new file mode 100644
index 0000000..87c3a2d
--- /dev/null
+++ b/rspec-expectations/lib/rspec/matchers/pretty.rb
@@ -0,0 +1,77 @@
+module RSpec
+  module Matchers
+    # @api private
+    # Contains logic to facilitate converting ruby symbols and
+    # objects to english phrases.
+    module Pretty
+      # @api private
+      # Converts a symbol into an english expression.
+      def split_words(sym)
+        sym.to_s.gsub(/_/, ' ')
+      end
+      module_function :split_words
+
+      # @api private
+      # Converts a collection of objects into an english expression.
+      def to_sentence(words)
+        return " #{words.inspect}" if !words || Struct === words
+        words = Array(words).map { |w| to_word(w) }
+        case words.length
+        when 0
+          ""
+        when 1
+          " #{words[0]}"
+        when 2
+          " #{words[0]} and #{words[1]}"
+        else
+          " #{words[0...-1].join(', ')}, and #{words[-1]}"
+        end
+      end
+
+      # @api private
+      # Converts the given item to string suitable for use in a list expression.
+      def to_word(item)
+        is_matcher_with_description?(item) ? item.description : item.inspect
+      end
+
+      # @private
+      # Provides an English expression for the matcher name.
+      def name_to_sentence
+        split_words(name)
+      end
+
+      # @api private
+      # Provides a name for the matcher.
+      def name
+        defined?(@name) ? @name : underscore(self.class.name.split("::").last)
+      end
+
+      # @private
+      # Borrowed from ActiveSupport
+      def underscore(camel_cased_word)
+        word = camel_cased_word.to_s.dup
+        word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
+        word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
+        word.tr!("-", "_")
+        word.downcase!
+        word
+      end
+
+    private
+
+      def is_matcher_with_description?(object)
+        RSpec::Matchers.is_a_matcher?(object) && object.respond_to?(:description)
+      end
+
+      # `{ :a => 5, :b => 2 }.inspect` produces:
+      #    {:a=>5, :b=>2}
+      # ...but it looks much better as:
+      #    {:a => 5, :b => 2}
+      #
+      # This is idempotent and safe to run on a string multiple times.
+      def improve_hash_formatting(inspect_string)
+        inspect_string.gsub(/(\S)=>(\S)/, '\1 => \2')
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/maintenance-branch b/rspec-expectations/maintenance-branch
new file mode 100644
index 0000000..8b25206
--- /dev/null
+++ b/rspec-expectations/maintenance-branch
@@ -0,0 +1 @@
+master
\ No newline at end of file
diff --git a/rspec-expectations/rspec-expectations.gemspec b/rspec-expectations/rspec-expectations.gemspec
new file mode 100644
index 0000000..54dc095
--- /dev/null
+++ b/rspec-expectations/rspec-expectations.gemspec
@@ -0,0 +1,46 @@
+# -*- encoding: utf-8 -*-
+$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
+require "rspec/expectations/version"
+
+Gem::Specification.new do |s|
+  s.name        = "rspec-expectations"
+  s.version     = RSpec::Expectations::Version::STRING
+  s.platform    = Gem::Platform::RUBY
+  s.license     = "MIT"
+  s.authors     = ["Steven Baker", "David Chelimsky", "Myron Marston"]
+  s.email       = "rspec at googlegroups.com"
+  s.homepage    = "http://github.com/rspec/rspec-expectations"
+  s.summary     = "rspec-expectations-#{RSpec::Expectations::Version::STRING}"
+  s.description = "rspec-expectations provides a simple, readable API to express expected outcomes of a code example."
+
+  s.rubyforge_project  = "rspec"
+
+  s.files            = `git ls-files -- lib/*`.split("\n")
+  s.files           += %w[README.md License.txt Changelog.md .yardopts .document]
+  s.test_files       = []
+  s.rdoc_options     = ["--charset=UTF-8"]
+  s.require_path     = "lib"
+
+  s.required_ruby_version = '>= 1.8.7'
+
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  if File.exist?(private_key)
+    s.signing_key = private_key
+    s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
+  end
+
+  if RSpec::Expectations::Version::STRING =~ /[a-zA-Z]+/
+    # pin to exact version for rc's and betas
+    s.add_runtime_dependency "rspec-support", "= #{RSpec::Expectations::Version::STRING}"
+  else
+    # pin to major/minor ignoring patch
+    s.add_runtime_dependency "rspec-support", "~> #{RSpec::Expectations::Version::STRING.split('.')[0..1].concat(['0']).join('.')}"
+  end
+
+  s.add_runtime_dependency "diff-lcs", ">= 1.2.0", "< 2.0"
+
+  s.add_development_dependency 'rake',     '~> 10.0.0'
+  s.add_development_dependency 'cucumber', '~> 1.3'
+  s.add_development_dependency "aruba",    "~> 0.6"
+  s.add_development_dependency 'minitest', '~> 5.2'
+end
diff --git a/rspec-expectations/script/clone_all_rspec_repos b/rspec-expectations/script/clone_all_rspec_repos
new file mode 100755
index 0000000..f83d2e9
--- /dev/null
+++ b/rspec-expectations/script/clone_all_rspec_repos
@@ -0,0 +1,24 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+if is_mri; then
+  pushd ..
+
+  clone_repo "rspec"
+  clone_repo "rspec-core"
+  clone_repo "rspec-expectations"
+  clone_repo "rspec-mocks"
+  clone_repo "rspec-rails"
+
+  if rspec_support_compatible; then
+    clone_repo "rspec-support"
+  fi
+
+  popd
+else
+  echo "Not cloning all repos since we are not on MRI and they are only needed for the MRI build"
+fi
diff --git a/rspec-expectations/script/functions.sh b/rspec-expectations/script/functions.sh
new file mode 100644
index 0000000..a96a5c7
--- /dev/null
+++ b/rspec-expectations/script/functions.sh
@@ -0,0 +1,129 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $SCRIPT_DIR/travis_functions.sh
+source $SCRIPT_DIR/predicate_functions.sh
+
+# idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
+export JRUBY_OPTS="${JRUBY_OPTS} -X-C" # disable JIT since these processes are so short lived
+SPECS_HAVE_RUN_FILE=specs.out
+MAINTENANCE_BRANCH=`cat maintenance-branch`
+
+function clone_repo {
+  if [ ! -d $1 ]; then # don't clone if the dir is already there
+    travis_retry eval "git clone git://github.com/rspec/$1 --depth 1 --branch $MAINTENANCE_BRANCH"
+  fi;
+}
+
+function run_specs_and_record_done {
+  local rspec_bin=bin/rspec
+
+  # rspec-core needs to run with a special script that loads simplecov first,
+  # so that it can instrument rspec-core's code before rspec-core has been loaded.
+  if [ -f script/rspec_with_simplecov ]; then
+    rspec_bin=script/rspec_with_simplecov
+  fi;
+
+  echo "${PWD}/bin/rspec"
+  $rspec_bin spec --backtrace --format progress --profile --format progress --out $SPECS_HAVE_RUN_FILE
+}
+
+function run_cukes {
+  if [ -d features ]; then
+    # force jRuby to use client mode JVM or a compilation mode thats as close as possible,
+    # idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
+    #
+    # Note that we delay setting this until we run the cukes because we've seen
+    # spec failures in our spec suite due to problems with this mode.
+    export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
+
+    echo "${PWD}/bin/cucumber"
+
+    if is_mri_192; then
+      # For some reason we get SystemStackError on 1.9.2 when using
+      # the bin/cucumber approach below. That approach is faster
+      # (as it avoids the bundler tax), so we use it on rubies where we can.
+      bundle exec cucumber --strict
+    else
+      # Prepare RUBYOPT for scenarios that are shelling out to ruby,
+      # and PATH for those that are using `rspec` or `rake`.
+      RUBYOPT="-I${PWD}/../bundle -rbundler/setup" \
+         PATH="${PWD}/bin:$PATH" \
+         bin/cucumber --strict
+    fi
+  fi
+}
+
+function run_specs_one_by_one {
+  echo "Running each spec file, one-by-one..."
+
+  for file in `find spec -iname '*_spec.rb'`; do
+    bin/rspec $file -b --format progress
+  done
+}
+
+function run_spec_suite_for {
+  if [ ! -f ../$1/$SPECS_HAVE_RUN_FILE ]; then # don't rerun specs that have already run
+    echo "Running specs for $1"
+    pushd ../$1
+    unset BUNDLE_GEMFILE
+    bundle_install_flags=`cat .travis.yml | grep bundler_args | tr -d '"' | grep -o " .*"`
+    travis_retry eval "bundle install $bundle_install_flags"
+    run_specs_and_record_done
+    popd
+  fi;
+}
+
+function check_documentation_coverage {
+  echo "bin/yard stats --list-undoc"
+
+  bin/yard stats --list-undoc | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      coverage ||= line[/([\d\.]+)% documented/, 1]
+      puts line
+    end
+
+    unless Float(coverage) == 100
+      puts \"\n\nMissing documentation coverage (currently at #{coverage}%)\"
+      exit(1)
+    end
+
+    if has_warnings
+      puts \"\n\nYARD emitted documentation warnings.\"
+      exit(1)
+    end
+  "
+
+  # Some warnings only show up when generating docs, so do that as well.
+  bin/yard doc --no-cache | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      has_errors   ||= line.start_with?('[error]:')
+      puts line
+    end
+
+    if has_warnings || has_errors
+      puts \"\n\nYARD emitted documentation warnings or errors.\"
+      exit(1)
+    end
+  "
+}
+
+function check_style_and_lint {
+  echo "bin/rubucop lib"
+  bin/rubocop lib
+}
+
+function run_all_spec_suites {
+  fold "one-by-one specs" run_specs_one_by_one
+  fold "rspec-core specs" run_spec_suite_for "rspec-core"
+  fold "rspec-expectations specs" run_spec_suite_for "rspec-expectations"
+  fold "rspec-mocks specs" run_spec_suite_for "rspec-mocks"
+  fold "rspec-rails specs" run_spec_suite_for "rspec-rails"
+
+  if rspec_support_compatible; then
+    fold "rspec-support specs" run_spec_suite_for "rspec-support"
+  fi
+}
diff --git a/rspec-expectations/script/predicate_functions.sh b/rspec-expectations/script/predicate_functions.sh
new file mode 100644
index 0000000..fc5d372
--- /dev/null
+++ b/rspec-expectations/script/predicate_functions.sh
@@ -0,0 +1,64 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+function is_mri {
+  if ruby -e "exit(!defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby')"; then
+    # RUBY_ENGINE only returns 'ruby' on MRI.
+    # MRI 1.8.7 lacks the constant but all other rubies have it (including JRuby in 1.8 mode)
+    return 0
+  else
+    return 1
+  fi;
+}
+
+function is_mri_192 {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION == '1.9.2')"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function is_mri_2plus {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION.to_f > 2.0)"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function rspec_support_compatible {
+  if [ "$MAINTENANCE_BRANCH" != "2-99-maintenance" ] && [ "$MAINTENANCE_BRANCH" != "2-14-maintenance" ]; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+function documentation_enforced {
+  if [ -x ./bin/yard ]; then
+    if is_mri_2plus; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function style_and_lint_enforced {
+ if [ -x ./bin/rubocop ]; then
+   return 0
+ else
+   return 1
+ fi
+}
diff --git a/rspec-expectations/script/run_build b/rspec-expectations/script/run_build
new file mode 100755
index 0000000..e1edcef
--- /dev/null
+++ b/rspec-expectations/script/run_build
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+# Allow repos to override the default functions and add their own
+if [ -f script/custom_build_functions.sh ]; then
+  source script/custom_build_functions.sh
+fi
+
+fold "specs" run_specs_and_record_done
+fold "cukes" run_cukes
+
+if documentation_enforced; then
+  fold "doc check" check_documentation_coverage
+fi
+
+if style_and_lint_enforced; then
+  fold "rubocop" check_style_and_lint
+fi
+
+if is_mri; then
+  run_all_spec_suites
+else
+  echo "Skipping the rest of the build on non-MRI rubies"
+fi
diff --git a/rspec-expectations/script/travis_functions.sh b/rspec-expectations/script/travis_functions.sh
new file mode 100644
index 0000000..77829b3
--- /dev/null
+++ b/rspec-expectations/script/travis_functions.sh
@@ -0,0 +1,69 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# Taken from:
+# https://github.com/travis-ci/travis-build/blob/e9314616e182a23e6a280199cd9070bfc7cae548/lib/travis/build/script/templates/header.sh#L34-L53
+travis_retry() {
+  local result=0
+  local count=1
+  while [ $count -le 3 ]; do
+    [ $result -ne 0 ] && {
+      echo -e "\n\033[33;1mThe command \"$@\" failed. Retrying, $count of 3.\033[0m\n" >&2
+    }
+    "$@"
+    result=$?
+    [ $result -eq 0 ] && break
+    count=$(($count + 1))
+    sleep 1
+  done
+
+  [ $count -eq 3 ] && {
+    echo "\n\033[33;1mThe command \"$@\" failed 3 times.\033[0m\n" >&2
+  }
+
+  return $result
+}
+
+# Taken from https://github.com/vcr/vcr/commit/fa96819c92b783ec0c794f788183e170e4f684b2
+# and https://github.com/vcr/vcr/commit/040aaac5370c68cd13c847c076749cd547a6f9b1
+nano_cmd="$(type -p gdate date | head -1)"
+nano_format="+%s%N"
+[ "$(uname -s)" != "Darwin" ] || nano_format="${nano_format/%N/000000000}"
+
+travis_time_start() {
+  travis_timer_id=$(printf %08x $(( RANDOM * RANDOM )))
+  travis_start_time=$($nano_cmd -u "$nano_format")
+  printf "travis_time:start:%s\r\e[0m" $travis_timer_id
+}
+
+travis_time_finish() {
+  local travis_end_time=$($nano_cmd -u "$nano_format")
+  local duration=$(($travis_end_time-$travis_start_time))
+  printf "travis_time:end:%s:start=%s,finish=%s,duration=%s\r\e[0m" \
+    $travis_timer_id $travis_start_time $travis_end_time $duration
+}
+
+fold() {
+  local name="$1"
+  local status=0
+  shift 1
+  if [ -n "$TRAVIS" ]; then
+    printf "travis_fold:start:%s\r\e[0m" "$name"
+    travis_time_start
+  fi
+
+  "$@"
+  status=$?
+
+  [ -z "$TRAVIS" ] || travis_time_finish
+
+  if [ "$status" -eq 0 ]; then
+    if [ -n "$TRAVIS" ]; then
+      printf "travis_fold:end:%s\r\e[0m" "$name"
+    fi
+  else
+    STATUS="$status"
+  fi
+
+  return $status
+}
diff --git a/rspec-expectations/spec/rspec/expectations/configuration_spec.rb b/rspec-expectations/spec/rspec/expectations/configuration_spec.rb
new file mode 100644
index 0000000..6e4b5d8
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/configuration_spec.rb
@@ -0,0 +1,226 @@
+require 'delegate'
+
+module RSpec
+  module Expectations
+    RSpec.describe Configuration do
+      let(:config) { Configuration.new }
+
+      describe "#backtrace_formatter" do
+        let(:original_backtrace) { %w[ clean-me/a.rb other/file.rb clean-me/b.rb ] }
+        let(:cleaned_backtrace)  { %w[ other/file.rb ] }
+
+        let(:formatted_backtrace) do
+          config.backtrace_formatter.format_backtrace(original_backtrace)
+        end
+
+        before do
+          @old_patterns = RSpec.configuration.backtrace_exclusion_patterns
+          @orig_full_backtrace = RSpec.configuration.full_backtrace?
+          RSpec.configuration.full_backtrace = false
+          RSpec.configuration.backtrace_exclusion_patterns = [/clean-me/]
+        end
+
+        after do
+          RSpec.configuration.backtrace_exclusion_patterns = @old_patterns
+          RSpec.configuration.full_backtrace = @orig_full_backtrace
+        end
+
+        it "defaults to rspec-core's backtrace formatter when rspec-core is loaded" do
+          expect(config.backtrace_formatter).to be(RSpec.configuration.backtrace_formatter)
+          expect(formatted_backtrace).to eq(cleaned_backtrace)
+        end
+
+        it "defaults to a null formatter when rspec-core is not loaded" do
+          RSpec::Mocks.with_temporary_scope do
+            rspec_dup = ::RSpec.dup
+            class << rspec_dup; undef configuration; end
+            stub_const("RSpec", rspec_dup)
+
+            expect(formatted_backtrace).to eq(original_backtrace)
+          end
+        end
+
+        it "can be set to another backtrace formatter" do
+          config.backtrace_formatter = double(:format_backtrace => ['a'])
+          expect(formatted_backtrace).to eq(['a'])
+        end
+      end
+
+      context 'on an interpreter that does not provide BasicObject', :uses_should, :unless => defined?(::BasicObject) do
+        before { RSpec::Expectations::Syntax.disable_should(Delegator) }
+
+        let(:klass) do
+          Class.new(SimpleDelegator) do
+            def delegated?; true; end
+          end
+        end
+
+        let(:instance) { klass.new(Object.new) }
+
+        it 'provides a means to manually add it Delegator' do
+          instance.should_not respond_to(:delegated?) # because #should is being delegated...
+          config.add_should_and_should_not_to Delegator
+          instance.should respond_to(:delegated?) # now it should work!
+        end
+      end
+
+      describe "#include_chain_clauses_in_custom_matcher_descriptions?" do
+        it "is false by default" do
+          expect(config.include_chain_clauses_in_custom_matcher_descriptions?).to be false
+        end
+
+        it "can be set to true" do
+          config.include_chain_clauses_in_custom_matcher_descriptions = true
+          expect(config.include_chain_clauses_in_custom_matcher_descriptions?).to be true
+        end
+
+        it "can be set back to false" do
+          config.include_chain_clauses_in_custom_matcher_descriptions = true
+          config.include_chain_clauses_in_custom_matcher_descriptions = false
+          expect(config.include_chain_clauses_in_custom_matcher_descriptions?).to be false
+        end
+      end
+
+      shared_examples "configuring the expectation syntax" do
+        before do
+          @orig_syntax = RSpec::Matchers.configuration.syntax
+        end
+
+        after do
+          configure_syntax(@orig_syntax)
+        end
+
+        it 'can limit the syntax to :should' do
+          configure_syntax :should
+          configured_syntax.should eq([:should])
+
+          3.should eq(3)
+          3.should_not eq(4)
+          lambda { expect(6).to eq(6) }.should raise_error(NameError)
+        end
+
+        it 'is a no-op when configured to :should twice' do
+          configure_syntax :should
+          method_added_count = 0
+          allow(Expectations::Syntax.default_should_host).to receive(:method_added) { method_added_count += 1 }
+          configure_syntax :should
+
+          method_added_count.should eq(0)
+        end
+
+        it 'can limit the syntax to :expect' do
+          configure_syntax :expect
+          expect(configured_syntax).to eq([:expect])
+
+          expect(3).to eq(3)
+          expect { 3.should eq(3) }.to raise_error(NameError)
+          expect { 3.should_not eq(3) }.to raise_error(NameError)
+        end
+
+        it 'is a no-op when configured to :expect twice' do
+          allow(RSpec::Matchers).to receive(:method_added).and_raise("no methods should be added here")
+
+          configure_syntax :expect
+          configure_syntax :expect
+        end
+
+        describe "`:should` being enabled by default deprecation" do
+          before { configure_default_syntax }
+
+          it "warns when the should syntax is called by default" do
+            expected_arguments = [
+              /Using.*without explicitly enabling/,
+              {:replacement=>"the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`"}
+            ]
+
+            expect(RSpec).to receive(:deprecate).with(*expected_arguments)
+            3.should eq(3)
+          end
+
+          it "includes the call site in the deprecation warning by default" do
+            expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
+            3.should eq(3)
+          end
+
+          it "does not warn when only the should syntax is explicitly configured" do
+            configure_syntax(:should)
+            RSpec.should_not receive(:deprecate)
+            3.should eq(3)
+          end
+
+          it "does not warn when both the should and expect syntaxes are explicitly configured" do
+            configure_syntax([:should, :expect])
+            expect(RSpec).not_to receive(:deprecate)
+            3.should eq(3)
+          end
+        end
+
+        it 'can re-enable the :should syntax' do
+          configure_syntax :expect
+          configure_syntax [:should, :expect]
+          configured_syntax.should eq([:should, :expect])
+
+          3.should eq(3)
+          3.should_not eq(4)
+          expect(3).to eq(3)
+        end
+
+        it 'can re-enable the :expect syntax' do
+          configure_syntax :should
+          configure_syntax [:should, :expect]
+          configured_syntax.should eq([:should, :expect])
+
+          3.should eq(3)
+          3.should_not eq(4)
+          expect(3).to eq(3)
+        end
+      end
+
+      def configure_default_syntax
+        RSpec::Matchers.configuration.reset_syntaxes_to_default
+      end
+
+      describe "configuring rspec-expectations directly" do
+        it_behaves_like "configuring the expectation syntax" do
+          def configure_syntax(syntax)
+            RSpec::Matchers.configuration.syntax = syntax
+          end
+
+          def configured_syntax
+            RSpec::Matchers.configuration.syntax
+          end
+        end
+      end
+
+      describe "configuring using the rspec-core config API" do
+        it_behaves_like "configuring the expectation syntax" do
+          def configure_syntax(syntax)
+            RSpec.configure do |rspec|
+              rspec.expect_with :rspec do |c|
+                c.syntax = syntax
+              end
+            end
+          end
+
+
+          def configured_syntax
+            RSpec.configure do |rspec|
+              rspec.expect_with :rspec do |c|
+                return c.syntax
+              end
+            end
+          end
+        end
+      end
+
+      it 'enables both syntaxes by default' do
+        # This is kinda a hack, but since we want to enforce use of
+        # the expect syntax within our specs here, we have modified the
+        # config setting, which makes it hard to get at the original
+        # default value. in spec_helper.rb we store the default value
+        # in $default_expectation_syntax so we can use it here.
+        expect($default_expectation_syntax).to contain_exactly(:expect, :should)
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/expectations/expectation_target_spec.rb b/rspec-expectations/spec/rspec/expectations/expectation_target_spec.rb
new file mode 100644
index 0000000..43a4eae
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/expectation_target_spec.rb
@@ -0,0 +1,147 @@
+module RSpec
+  module Expectations
+    # so our examples below can set expectations about the target
+    ExpectationTarget.send(:attr_reader, :target)
+
+    RSpec.describe ExpectationTarget do
+      context 'when constructed via #expect' do
+        it 'constructs a new instance targetting the given argument' do
+          expect(expect(7).target).to eq(7)
+        end
+
+        it 'constructs a new instance targetting the given block' do
+          block = lambda {}
+          expect(expect(&block).target).to be(block)
+        end
+
+        it 'raises an ArgumentError when given an argument and a block' do
+          expect {
+            expect(7) { }
+          }.to raise_error(ArgumentError)
+        end
+
+        it 'raises a wrong number of args ArgumentError when given two args' do
+          expect {
+            expect(1, 2)
+          }.to raise_error(ArgumentError, /wrong number of arg/)
+        end
+
+        it 'raises an ArgumentError when given neither an argument nor a block' do
+          expect {
+            expect
+          }.to raise_error(ArgumentError)
+        end
+
+        it 'can be passed nil' do
+          expect(expect(nil).target).to be_nil
+        end
+
+        it 'passes a valid positive expectation' do
+          expect(5).to eq(5)
+        end
+
+        it 'passes a valid negative expectation' do
+          expect(5).not_to eq(4)
+        end
+
+        it 'passes a valid negative expectation with a split infinitive' do
+          expect(5).to_not eq(4)
+        end
+
+        it 'fails an invalid positive expectation' do
+          expect {
+            expect(5).to eq(4)
+          }.to fail_with(/expected: 4.*got: 5/m)
+        end
+
+        it 'fails an invalid negative expectation' do
+          message = /expected 5 not to be a kind of Fixnum/
+          expect {
+            expect(5).not_to be_a(Fixnum)
+          }.to fail_with(message)
+        end
+
+        it 'fails an invalid negative expectation with a split infinitive' do
+          message = /expected 5 not to be a kind of Fixnum/
+          expect {
+            expect(5).to_not be_a(Fixnum)
+          }.to fail_with(message)
+        end
+
+        it 'does not support operator matchers from #to' do
+          expect {
+            expect(3).to == 3
+          }.to raise_error(ArgumentError)
+        end
+
+        it 'does not support operator matchers from #not_to' do
+          expect {
+            expect(3).not_to == 4
+          }.to raise_error(ArgumentError)
+        end
+      end
+
+      context "when passed a block" do
+        it 'can be used with a block matcher' do
+          expect { }.not_to raise_error
+        end
+
+        context 'when passed a value matcher' do
+          not_a_block_matcher_error = /You must pass an argument rather than a block to use the provided matcher/
+
+          it 'raises an error that directs the user to pass an arg rather than a block' do
+            expect {
+              expect { }.to be_an(Object)
+            }.to fail_with(not_a_block_matcher_error)
+
+            expect {
+              expect { }.not_to be_nil
+            }.to fail_with(not_a_block_matcher_error)
+
+            expect {
+              expect { }.to_not be_nil
+            }.to fail_with(not_a_block_matcher_error)
+          end
+
+          it 'assumes a custom matcher that does not define `supports_block_expectations?` is not a block matcher (since it is relatively rare)' do
+            custom_matcher = Module.new do
+              def self.matches?(value); true; end
+              def self.description; "foo"; end
+            end
+
+            expect(3).to custom_matcher # to show the custom matcher can be used as a matcher
+
+            expect {
+              expect { 3 }.to custom_matcher
+            }.to fail_with(not_a_block_matcher_error)
+          end
+
+          it "uses the matcher's `description` in the error message" do
+            custom_matcher = Module.new do
+              def self.supports_block_expectations?; false; end
+              def self.description; "matcher-description"; end
+            end
+
+            expect {
+              expect { }.to custom_matcher
+            }.to fail_with(/\(matcher-description\)/)
+          end
+
+          context 'when the matcher does not define `description` (since it is an optional part of the protocol)' do
+            it 'uses `inspect` in the error message instead' do
+              custom_matcher = Module.new do
+                def self.supports_block_expectations?; false; end
+                def self.inspect; "matcher-inspect"; end
+              end
+
+              expect {
+                expect { }.to custom_matcher
+              }.to fail_with(/\(matcher-inspect\)/)
+            end
+          end
+        end
+      end
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/expectations/extensions/kernel_spec.rb b/rspec-expectations/spec/rspec/expectations/extensions/kernel_spec.rb
new file mode 100644
index 0000000..cbde1d3
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/extensions/kernel_spec.rb
@@ -0,0 +1,69 @@
+RSpec.describe Object, "#should" do
+  before(:example) do
+    @target = "target"
+    @matcher = double("matcher")
+    allow(@matcher).to receive(:matches?).and_return(true)
+    allow(@matcher).to receive(:failure_message)
+  end
+
+  it "accepts and interacts with a matcher" do
+    expect(@matcher).to receive(:matches?).with(@target).and_return(true)
+    expect(@target).to @matcher
+  end
+
+  it "asks for a failure_message when matches? returns false" do
+    expect(@matcher).to receive(:matches?).with(@target).and_return(false)
+    expect(@matcher).to receive(:failure_message).and_return("the failure message")
+    expect {
+      expect(@target).to @matcher
+    }.to fail_with("the failure message")
+  end
+
+  context "on interpretters that have BasicObject", :if => defined?(BasicObject) do
+    let(:proxy_class) do
+      Class.new(BasicObject) do
+        def initialize(target)
+          @target = target
+        end
+
+        def proxied?
+          true
+        end
+
+        def respond_to?(method, *args)
+          method.to_sym == :proxied? || @target.respond_to?(symbol, *args)
+        end
+
+        def method_missing(name, *args)
+          @target.send(name, *args)
+        end
+      end
+    end
+
+    it 'works properly on BasicObject-subclassed proxy objects' do
+      expect(proxy_class.new(Object.new)).to be_proxied
+    end
+  end
+end
+
+RSpec.describe Object, "#should_not" do
+  before(:example) do
+    @target = "target"
+    @matcher = double("matcher")
+  end
+
+  it "accepts and interacts with a matcher" do
+    expect(@matcher).to receive(:matches?).with(@target).and_return(false)
+    allow(@matcher).to receive(:failure_message_when_negated)
+
+    expect(@target).not_to @matcher
+  end
+
+  it "asks for a failure_message_when_negated when matches? returns true" do
+    expect(@matcher).to receive(:matches?).with(@target).and_return(true)
+    expect(@matcher).to receive(:failure_message_when_negated).and_return("the failure message for should not")
+    expect {
+      expect(@target).not_to @matcher
+    }.to fail_with("the failure message for should not")
+  end
+end
diff --git a/rspec-expectations/spec/rspec/expectations/fail_with_spec.rb b/rspec-expectations/spec/rspec/expectations/fail_with_spec.rb
new file mode 100644
index 0000000..e8e2e2e
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/fail_with_spec.rb
@@ -0,0 +1,73 @@
+# encoding: utf-8
+
+RSpec.describe RSpec::Expectations, "#fail_with" do
+  let(:differ) { double("differ") }
+
+  before(:example) do
+    allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)
+    allow(RSpec::Expectations).to receive(:differ) { differ }
+  end
+
+  it "includes a diff if expected and actual are diffable" do
+    expect(differ).to receive(:diff).and_return("diff text")
+
+    expect {
+      RSpec::Expectations.fail_with "message", "abc", "def"
+    }.to fail_with("message\nDiff:diff text")
+  end
+
+  it "does not include the diff if expected and actual are not diffable" do
+    expect(differ).to receive(:diff).and_return("")
+
+    expect {
+      RSpec::Expectations.fail_with "message", "abc", "def"
+    }.to fail_with("message")
+  end
+
+  it "raises an error if message is not present" do
+    expect(differ).not_to receive(:diff)
+
+    expect {
+      RSpec::Expectations.fail_with nil
+    }.to raise_error(ArgumentError, /Failure message is nil\./)
+  end
+end
+
+RSpec.describe RSpec::Expectations, "#fail_with with matchers" do
+  before do
+    allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)
+  end
+
+  it "uses matcher descriptions in place of matchers in diffs" do
+    expected = [a_string_matching(/foo/), a_string_matching(/bar/)]
+    actual = ["poo", "car"]
+
+    expected_diff = dedent(<<-EOS)
+      |
+      |@@ -1,2 +1,2 @@
+      |-["poo", "car"]
+      |+[(a string matching /foo/), (a string matching /bar/)]
+      |
+    EOS
+
+    expect {
+      RSpec::Expectations.fail_with "message", actual, expected
+    }.to fail_with("message\nDiff:#{expected_diff}")
+  end
+end
+
+RSpec.describe RSpec::Expectations, "#fail_with with --color" do
+  before do
+    allow(RSpec::Matchers.configuration).to receive_messages(:color? => true)
+  end
+
+  it "tells the differ to use color" do
+    expected = "foo bar baz\n"
+    actual = "foo bang baz\n"
+    expected_diff = "\e[0m\n\e[0m\e[34m@@ -1,2 +1,2 @@\n\e[0m\e[31m-foo bang baz\n\e[0m\e[32m+foo bar baz\n\e[0m"
+
+    expect {
+      RSpec::Expectations.fail_with "message", actual, expected
+    }.to fail_with("message\nDiff:#{expected_diff}")
+  end
+end
diff --git a/rspec-expectations/spec/rspec/expectations/handler_spec.rb b/rspec-expectations/spec/rspec/expectations/handler_spec.rb
new file mode 100644
index 0000000..8583a4b
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/handler_spec.rb
@@ -0,0 +1,200 @@
+module ExampleExpectations
+
+  class ArbitraryMatcher
+    def initialize(*args, &block)
+      if args.last.is_a? Hash
+        @expected = args.last[:expected]
+      end
+      @expected = block.call if block
+      @block = block
+    end
+
+    def matches?(target)
+      @target = target
+      return @expected == target
+    end
+
+    def with(new_value)
+      @expected = new_value
+      self
+    end
+
+    def failure_message
+      "expected #{@expected}, got #{@target}"
+    end
+
+    def failure_message_when_negated
+      "expected not #{@expected}, got #{@target}"
+    end
+  end
+
+  class PositiveOnlyMatcher < ArbitraryMatcher
+    undef failure_message_when_negated rescue nil
+  end
+
+  def arbitrary_matcher(*args, &block)
+    ArbitraryMatcher.new(*args, &block)
+  end
+
+  def positive_only_matcher(*args, &block)
+    PositiveOnlyMatcher.new(*args, &block)
+  end
+
+end
+
+module RSpec
+  module Expectations
+    RSpec.describe PositiveExpectationHandler do
+      include ExampleExpectations
+
+      it "handles submitted args" do
+        expect(5).to arbitrary_matcher(:expected => 5)
+        expect(5).to arbitrary_matcher(:expected => "wrong").with(5)
+        expect { expect(5).to arbitrary_matcher(:expected => 4) }.to fail_with("expected 4, got 5")
+        expect { expect(5).to arbitrary_matcher(:expected => 5).with(4) }.to fail_with("expected 4, got 5")
+        expect(5).not_to arbitrary_matcher(:expected => 4)
+        expect(5).not_to arbitrary_matcher(:expected => 5).with(4)
+        expect { expect(5).not_to arbitrary_matcher(:expected => 5) }.to fail_with("expected not 5, got 5")
+        expect { expect(5).not_to arbitrary_matcher(:expected => 4).with(5) }.to fail_with("expected not 5, got 5")
+      end
+
+      it "handles the submitted block" do
+        expect(5).to arbitrary_matcher { 5 }
+        expect(5).to arbitrary_matcher(:expected => 4) { 5 }
+        expect(5).to arbitrary_matcher(:expected => 4).with(5) { 3 }
+      end
+
+      describe "#handle_matcher" do
+        it "asks the matcher if it matches" do
+          matcher = double("matcher")
+          actual = Object.new
+          expect(matcher).to receive(:matches?).with(actual).and_return(true)
+          RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher)
+        end
+
+        it "returns the match value" do
+          matcher = double("matcher")
+          actual = Object.new
+          expect(matcher).to receive(:matches?).with(actual).and_return(:this_value)
+          expect(RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher)).to eq :this_value
+        end
+
+        it "calls failure_message if the matcher implements it" do
+          matcher = double("matcher", :failure_message => "message", :matches? => false)
+          actual = Object.new
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("message")
+
+          RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher)
+        end
+
+        it "calls fail if matcher.diffable?" do
+          matcher = double("matcher",
+            :diffable? => true,
+            :failure_message => "message",
+            :matches? => false,
+            :expected => 1,
+            :actual   => 2
+          )
+          actual = Object.new
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("message", 1, 2)
+
+          RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher)
+        end
+
+        it "calls failure_message if the matcher does not implement failure_message" do
+          matcher = double("matcher", :failure_message => "message", :matches? => false)
+          actual = Object.new
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("message")
+
+          RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher)
+
+        end
+
+        it "uses the custom failure message when one is provided" do
+          matcher = double("matcher", :failure_message => "message", :matches? => false)
+          actual = Object.new
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("custom")
+
+          RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher, "custom")
+        end
+
+        it "uses the custom failure message when one is provided as a callable object" do
+          matcher = double("matcher", :failure_message => "message", :matches? => false)
+          actual = Object.new
+
+          failure_message = double("failure message", :call => "custom")
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("custom")
+
+          RSpec::Expectations::PositiveExpectationHandler.handle_matcher(actual, matcher, failure_message)
+        end
+      end
+    end
+
+    RSpec.describe NegativeExpectationHandler do
+      describe "#handle_matcher" do
+        it "asks the matcher if it doesn't match when the matcher responds to #does_not_match?" do
+          matcher = double("matcher", :does_not_match? => true, :failure_message_when_negated => nil)
+          actual = Object.new
+          expect(matcher).to receive(:does_not_match?).with(actual).and_return(true)
+          RSpec::Expectations::NegativeExpectationHandler.handle_matcher(actual, matcher)
+        end
+
+        it "asks the matcher if it matches when the matcher doesn't respond to #does_not_match?" do
+          matcher = double("matcher")
+          actual = Object.new
+          allow(matcher).to receive(:failure_message_when_negated)
+          expect(matcher).to receive(:matches?).with(actual).and_return(false)
+          RSpec::Expectations::NegativeExpectationHandler.handle_matcher(actual, matcher)
+        end
+
+        it "returns the match value" do
+          matcher = double("matcher")
+          actual = Object.new
+          expect(matcher).to receive(:matches?).with(actual).and_return(false)
+          allow(matcher).to receive(:failure_message_when_negated).and_return("ignore")
+          expect(RSpec::Expectations::NegativeExpectationHandler.handle_matcher(actual, matcher)).to be_falsey
+        end
+
+        it "calls fail if matcher.diffable?" do
+          matcher = double("matcher",
+            :diffable? => true,
+            :failure_message_when_negated => "message",
+            :matches? => true,
+            :expected => 1,
+            :actual   => 2
+          )
+          actual = Object.new
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("message", 1, 2)
+
+          RSpec::Expectations::NegativeExpectationHandler.handle_matcher(actual, matcher)
+        end
+
+        it "uses the custom failure message when one is provided" do
+          matcher = double("matcher", :failure_message_when_negated => "message", :matches? => true)
+          actual = Object.new
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("custom")
+
+          RSpec::Expectations::NegativeExpectationHandler.handle_matcher(actual, matcher, "custom")
+        end
+
+        it "uses the custom failure message when one is provided as a callable object" do
+          matcher = double("matcher", :failure_message_when_negated => "message", :matches? => true)
+          actual = Object.new
+
+          failure_message = double("failure message", :call => "custom")
+
+          expect(::RSpec::Expectations).to receive(:fail_with).with("custom")
+
+          RSpec::Expectations::NegativeExpectationHandler.handle_matcher(actual, matcher, failure_message)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/expectations/minitest_integration_spec.rb b/rspec-expectations/spec/rspec/expectations/minitest_integration_spec.rb
new file mode 100644
index 0000000..e273d4a
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/minitest_integration_spec.rb
@@ -0,0 +1,25 @@
+module RSpec
+  RSpec.describe Matchers do
+
+    let(:sample_matchers) do
+      [:be,
+       :be_instance_of,
+       :be_kind_of]
+    end
+
+    context "once required", :slow do
+      include MinitestIntegration
+
+      it "includes itself in Minitest::Test" do
+        with_minitest_loaded do
+          minitest_case = MiniTest::Test.allocate
+          sample_matchers.each do |sample_matcher|
+              expect(minitest_case).to respond_to(sample_matcher)
+          end
+        end
+      end
+
+    end
+
+  end
+end
diff --git a/rspec-expectations/spec/rspec/expectations/syntax_spec.rb b/rspec-expectations/spec/rspec/expectations/syntax_spec.rb
new file mode 100644
index 0000000..a1b147f
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations/syntax_spec.rb
@@ -0,0 +1,93 @@
+module RSpec
+  module Expectations
+    RSpec.describe Syntax do
+      context "when passing a message to an expectation" do
+        let(:warner) { ::Kernel }
+
+        let(:string_like_object) do
+          Struct.new(:to_str, :to_s).new(*(["Ceci n'est pas une Chaine."]*2))
+        end
+
+        let(:insufficiently_string_like_object) do
+          Struct.new(:to_s).new("Ceci n'est pas une Chaine.")
+        end
+
+        let(:callable_object) do
+          Struct.new(:call).new("Ceci n'est pas une Chaine.")
+        end
+
+        describe "expect(...).to" do
+          it "prints a warning when the message object isn't a String" do
+            expect(warner).to receive(:warn).with(/ignoring.*message/)
+            expect(3).to eq(3), :not_a_string
+          end
+
+          it "doesn't print a warning when message is a String" do
+            expect(warner).not_to receive(:warn)
+            expect(3).to eq(3), "a string"
+          end
+
+          it "doesn't print a warning when message responds to to_str" do
+            expect(warner).not_to receive(:warn)
+            expect(3).to eq(3), string_like_object
+          end
+
+          it "prints a warning when the message object handles to_s but not to_str" do
+            expect(warner).to receive(:warn).with(/ignoring.*message/)
+            expect(3).to eq(3), insufficiently_string_like_object
+          end
+
+          it "doesn't print a warning when message responds to call" do
+            expect(warner).not_to receive(:warn)
+            expect(3).to eq(3), callable_object
+          end
+        end
+
+        describe "expect(...).not_to" do
+          it "prints a warning when the message object isn't a String" do
+            expect(warner).to receive(:warn).with(/ignoring.*message/)
+            expect(3).not_to eq(4), :not_a_string
+          end
+
+          it "doesn't print a warning when message is a String" do
+            expect(warner).not_to receive(:warn)
+            expect(3).not_to eq(4), "a string"
+          end
+
+          it "doesn't print a warning when message responds to to_str" do
+            expect(warner).not_to receive(:warn)
+            expect(3).not_to eq(4), string_like_object
+          end
+
+          it "prints a warning when the message object handles to_s but not to_str" do
+            expect(warner).to receive(:warn).with(/ignoring.*message/)
+            expect(3).not_to eq(4), insufficiently_string_like_object
+          end
+
+          it "doesn't print a warning when message responds to call" do
+            expect(warner).not_to receive(:warn)
+            expect(3).not_to eq(4), callable_object
+          end
+        end
+      end
+
+      describe "enabling the should syntax on something other than the default syntax host" do
+        include_context "with the default expectation syntax"
+
+        it "continues to warn about the should syntax" do
+          my_host = Class.new
+          expect(RSpec).to receive(:deprecate)
+          Syntax.enable_should(my_host)
+
+          3.should eq 3
+        end
+      end
+    end
+  end
+
+  RSpec.describe Expectations do
+    it "does not inadvertently define BasicObject on 1.8", :if => RUBY_VERSION.to_f < 1.9 do
+      expect(defined?(::BasicObject)).to be nil
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/expectations_spec.rb b/rspec-expectations/spec/rspec/expectations_spec.rb
new file mode 100644
index 0000000..76306ef
--- /dev/null
+++ b/rspec-expectations/spec/rspec/expectations_spec.rb
@@ -0,0 +1,15 @@
+require 'rspec/support/spec/prevent_load_time_warnings'
+
+RSpec.describe "RSpec::Expectations" do
+  it_behaves_like 'a library that issues no warnings when loaded', 'rspec-expectations',
+    # We define minitest constants because rspec/expectations/minitest_integration
+    # expects these constants to already be defined.
+    'module Minitest; class Assertion; end; module Test; end; end',
+    'require "rspec/expectations"'
+
+  it 'does not allow expectation failures to be caught by a bare rescue' do
+    expect {
+      expect(2).to eq(3) rescue nil
+    }.to fail_matching("expected: 3")
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/aliased_matcher_spec.rb b/rspec-expectations/spec/rspec/matchers/aliased_matcher_spec.rb
new file mode 100644
index 0000000..0ed5f9c
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/aliased_matcher_spec.rb
@@ -0,0 +1,113 @@
+module RSpec
+  module Matchers
+    RSpec.describe AliasedMatcher do
+      RSpec::Matchers.define :my_base_matcher do
+        match { |actual| actual == foo }
+
+        def foo
+          13
+        end
+
+        def description
+          "my base matcher description"
+        end
+      end
+      RSpec::Matchers.alias_matcher :alias_of_my_base_matcher, :my_base_matcher
+
+      it_behaves_like "an RSpec matcher", :valid_value => 13, :invalid_value => nil do
+        let(:matcher) { alias_of_my_base_matcher }
+      end
+
+      shared_examples "making a copy" do |copy_method|
+        context "when making a copy via `#{copy_method}`" do
+          it "uses a copy of the base matcher" do
+            base_matcher = include(3)
+            aliased = AliasedMatcher.new(base_matcher, Proc.new {})
+            copy = aliased.__send__(copy_method)
+
+            expect(copy).not_to equal(aliased)
+            expect(copy.base_matcher).not_to equal(base_matcher)
+            expect(copy.base_matcher).to be_a(RSpec::Matchers::BuiltIn::Include)
+            expect(copy.base_matcher.expected).to eq([3])
+          end
+
+          it "copies custom matchers properly so they can work even though they have singleton behavior" do
+            base_matcher = my_base_matcher
+            aliased = AliasedMatcher.new(base_matcher, Proc.new { |a| a })
+            copy = aliased.__send__(copy_method)
+
+            expect(copy).not_to equal(aliased)
+            expect(copy.base_matcher).not_to equal(base_matcher)
+
+            expect(13).to copy
+
+            expect { expect(15).to copy }.to fail_with(/expected 15/)
+          end
+        end
+      end
+
+      include_examples "making a copy", :dup
+      include_examples "making a copy", :clone
+
+      it 'can get a method object for delegated methods', :if => (RUBY_VERSION.to_f > 1.8) do
+        matcher = my_base_matcher
+        decorated = AliasedMatcher.new(matcher, Proc.new { })
+
+        expect(decorated.method(:foo).call).to eq(13)
+      end
+
+      it 'can get a method object for `description`' do
+        matcher = my_base_matcher
+        decorated = AliasedMatcher.new(matcher, Proc.new { "overriden description" })
+
+        expect(decorated.method(:description).call).to eq("overriden description")
+      end
+
+      RSpec::Matchers.alias_matcher :my_overriden_matcher, :my_base_matcher do |desc|
+        desc + " (overriden)"
+      end
+
+      it 'overrides the description with the provided block' do
+        matcher = my_overriden_matcher
+        expect(matcher.description).to eq("my base matcher description (overriden)")
+      end
+
+      RSpec::Matchers.alias_matcher :my_blockless_override, :my_base_matcher
+
+      it 'provides a default description override based on the old and new games' do
+        matcher = my_blockless_override
+        expect(matcher.description).to eq("my blockless override description")
+      end
+
+      RSpec::Matchers.define_negated_matcher :avoid_outputting, :output
+
+      it 'works properly with a chained method off a negated matcher' do
+        expect { }.to avoid_outputting.to_stdout
+
+        expect {
+          expect { $stdout.puts "a" }.to avoid_outputting.to_stdout
+        }.to fail
+      end
+
+      context "when negating a matcher that does not define `description` (which is an optional part of the matcher protocol)" do
+        def matcher_without_description
+          matcher = Object.new
+          def matcher.matches?(v); v; end
+          def matcher.failure_message; "match failed"; end
+          def matcher.chained; self; end
+          expect(RSpec::Matchers.is_a_matcher?(matcher)).to be true
+
+          matcher
+        end
+
+        RSpec::Matchers.define_negated_matcher :negation_of_matcher_without_description, :matcher_without_description
+
+        it 'works properly' do
+          expect(true).to matcher_without_description.chained
+          expect(false).to negation_of_matcher_without_description.chained
+        end
+      end
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers/aliases_spec.rb b/rspec-expectations/spec/rspec/matchers/aliases_spec.rb
new file mode 100644
index 0000000..5038b82
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/aliases_spec.rb
@@ -0,0 +1,455 @@
+module RSpec
+  RSpec.describe Matchers, "aliases", :order => :defined do
+    matcher :be_aliased_to do |old_matcher|
+      chain :with_description do |desc|
+        @expected_desc = desc
+      end
+
+      match do |aliased_matcher|
+        @actual_desc = aliased_matcher.description
+
+        @actual_desc == @expected_desc &&
+        aliased_matcher.base_matcher.class == old_matcher.class
+      end
+
+      failure_message do |aliased_matcher|
+        "expected #{aliased_matcher} to be aliased to #{old_matcher} with " +
+        "description: #{@expected_desc.inspect}, but got #{@actual_desc.inspect}"
+      end
+
+      description do |aliased_matcher|
+        "have an alias for #{old_matcher.description.inspect} with description: #{@expected_desc.inspect}"
+      end
+    end
+
+    specify do
+      expect(a_truthy_value).to be_aliased_to(be_truthy).with_description("a truthy value")
+    end
+
+    specify do
+      expect(a_falsey_value).to be_aliased_to(be_falsey).with_description("a falsey value")
+    end
+
+    specify do
+      expect(be_falsy).to be_aliased_to(be_falsey).with_description("be falsy")
+    end
+
+    specify do
+      expect(a_falsy_value).to be_aliased_to(be_falsey).with_description("a falsy value")
+    end
+
+    specify do
+      expect(a_nil_value).to be_aliased_to(be_nil).with_description("a nil value")
+    end
+
+    specify do
+      expect(a_value > 3).to be_aliased_to(be > 3).with_description("a value > 3")
+    end
+
+    specify do
+      expect(a_value < 3).to be_aliased_to(be < 3).with_description("a value < 3")
+    end
+
+    specify do
+      expect(a_value <= 3).to be_aliased_to(be <= 3).with_description("a value <= 3")
+    end
+
+    specify do
+      expect(a_value == 3).to be_aliased_to(be == 3).with_description("a value == 3")
+    end
+
+    specify do
+      expect(a_value === 3).to be_aliased_to(be === 3).with_description("a value === 3")
+    end
+
+    specify do
+      expect(
+        an_instance_of(Integer)
+      ).to be_aliased_to(
+        be_an_instance_of(Integer)
+      ).with_description("an instance of Integer")
+    end
+
+    specify do
+      expect(
+        a_kind_of(Integer)
+      ).to be_aliased_to(
+        be_a_kind_of(Integer)
+      ).with_description("a kind of Integer")
+    end
+
+    specify do
+      expect(
+        a_value_between(1, 10)
+      ).to be_aliased_to(
+        be_between(1, 10)
+      ).with_description("a value between 1 and 10 (inclusive)")
+    end
+
+    specify do
+      expect(
+        a_value_within(0.1).of(3)
+      ).to be_aliased_to(
+        be_within(0.1).of(3)
+      ).with_description("a value within 0.1 of 3")
+    end
+
+    specify do
+      expect(
+        within(0.1).of(3)
+      ).to be_aliased_to(
+        be_within(0.1).of(3)
+      ).with_description("within 0.1 of 3")
+    end
+
+    specify do
+      expect(a_block_changing).to be_aliased_to(change).with_description("a block changing result")
+    end
+
+    specify do
+      expect(changing).to be_aliased_to(change).with_description("changing result")
+    end
+
+    specify do
+      expect(
+        a_collection_containing_exactly(1, 2)
+      ).to be_aliased_to(
+        contain_exactly(1, 2)
+      ).with_description("a collection containing exactly 1 and 2")
+    end
+
+    specify do
+      expect(
+        containing_exactly(1, 2)
+      ).to be_aliased_to(
+        contain_exactly(1, 2)
+      ).with_description("containing exactly 1 and 2")
+    end
+
+    specify do
+      expect(
+        a_range_covering(1, 2)
+      ).to be_aliased_to(
+        cover(1, 2)
+      ).with_description("a range covering 1 and 2")
+    end
+
+    specify do
+      expect(
+        covering(1, 2)
+      ).to be_aliased_to(
+        cover(1, 2)
+      ).with_description("covering 1 and 2")
+    end
+
+    specify do
+      expect(
+        ending_with(23)
+      ).to be_aliased_to(
+        end_with(23)
+      ).with_description("ending with 23")
+    end
+
+    specify do
+      expect(
+        a_collection_ending_with(23)
+      ).to be_aliased_to(
+        end_with(23)
+      ).with_description("a collection ending with 23")
+    end
+
+    specify do
+      expect(
+        a_string_ending_with("z")
+      ).to be_aliased_to(
+        end_with("z")
+      ).with_description('a string ending with "z"')
+    end
+
+    specify do
+      expect(
+        an_object_eq_to(3)
+      ).to be_aliased_to(eq 3).with_description("an object eq to 3")
+    end
+
+    specify do
+      expect(
+        eq_to(3)
+      ).to be_aliased_to(eq 3).with_description("eq to 3")
+    end
+
+    specify do
+      expect(
+        an_object_eql_to(3)
+      ).to be_aliased_to(eql 3).with_description("an object eql to 3")
+    end
+
+    specify do
+      expect(
+        eql_to(3)
+      ).to be_aliased_to(eql 3).with_description("eql to 3")
+    end
+
+    specify do
+      expect(
+        an_object_equal_to(3)
+      ).to be_aliased_to(equal 3).with_description("an object equal to 3")
+    end
+
+    specify do
+      expect(
+        equal_to(3)
+      ).to be_aliased_to(equal 3).with_description("equal to 3")
+    end
+
+    specify do
+      expect(
+        an_object_existing
+      ).to be_aliased_to(exist).with_description("an object existing")
+    end
+
+    specify do
+      expect(existing).to be_aliased_to(exist).with_description("existing")
+    end
+
+    specify do
+      expect(
+          an_object_having_attributes(:age => 32)
+      ).to be_aliased_to(
+          have_attributes(:age => 32)
+      ).with_description("an object having attributes {:age => 32}")
+    end
+
+    specify do
+      expect(
+        a_string_including("a")
+      ).to be_aliased_to(
+        include("a")
+      ).with_description('a string including "a"')
+    end
+
+    specify do
+      expect(
+        a_collection_including("a")
+      ).to be_aliased_to(
+        include("a")
+      ).with_description('a collection including "a"')
+    end
+
+    specify do
+      expect(
+        a_hash_including(:a => 5)
+      ).to be_aliased_to(
+        include(:a => 5)
+      ).with_description('a hash including {:a => 5}')
+    end
+
+    specify do
+      expect(
+        including(3)
+      ).to be_aliased_to(
+        include(3)
+      ).with_description('including 3')
+    end
+
+    specify do
+      expect(
+        a_string_matching(/foo/)
+      ).to be_aliased_to(
+        match(/foo/)
+      ).with_description('a string matching /foo/')
+    end
+
+    specify do
+      expect(
+        an_object_matching(/foo/)
+      ).to be_aliased_to(
+        match(/foo/)
+      ).with_description('an object matching /foo/')
+    end
+
+    specify do
+      expect(
+        match_regex(/foo/)
+      ).to be_aliased_to(
+        match(/foo/)
+      ).with_description('match regex /foo/')
+    end
+
+    specify do
+      expect(
+        matching(/foo/)
+      ).to be_aliased_to(
+        match(/foo/)
+      ).with_description('matching /foo/')
+    end
+
+    specify do
+      expect(
+        a_block_outputting('foo').to_stdout
+      ).to be_aliased_to(
+        output('foo').to_stdout
+      ).with_description('a block outputting "foo" to stdout')
+    end
+
+    specify do
+      expect(
+        a_block_outputting('foo').to_stderr
+      ).to be_aliased_to(
+        output('foo').to_stderr
+      ).with_description('a block outputting "foo" to stderr')
+    end
+
+    specify do
+      expect(
+        a_block_raising(ArgumentError)
+      ).to be_aliased_to(
+        raise_error(ArgumentError)
+      ).with_description('a block raising ArgumentError')
+    end
+
+    specify do
+      expect(
+        raising(ArgumentError)
+      ).to be_aliased_to(
+        raise_error(ArgumentError)
+      ).with_description("raising ArgumentError")
+    end
+
+    specify do
+      expect(
+        an_object_responding_to(:foo)
+      ).to be_aliased_to(
+        respond_to(:foo)
+      ).with_description("an object responding to #foo")
+    end
+
+    specify do
+      expect(
+        responding_to(:foo)
+      ).to be_aliased_to(
+        respond_to(:foo)
+      ).with_description("responding to #foo")
+    end
+
+    specify do
+      expect(
+        an_object_satisfying { }
+      ).to be_aliased_to(
+        satisfy { }
+      ).with_description("an object satisfying block")
+    end
+
+    specify do
+      expect(
+        satisfying { }
+      ).to be_aliased_to(
+        satisfy { }
+      ).with_description("satisfying block")
+    end
+
+    specify do
+      expect(
+        a_collection_starting_with(23)
+      ).to be_aliased_to(
+        start_with(23)
+      ).with_description("a collection starting with 23")
+    end
+
+    specify do
+      expect(
+        a_string_starting_with("z")
+      ).to be_aliased_to(
+        start_with("z")
+      ).with_description('a string starting with "z"')
+    end
+
+    specify do
+      expect(
+        starting_with("d")
+      ).to be_aliased_to(
+        start_with("d")
+      ).with_description('starting with "d"')
+    end
+
+    specify do
+      expect(
+        a_block_throwing(:foo)
+      ).to be_aliased_to(
+        throw_symbol(:foo)
+      ).with_description("a block throwing :foo")
+    end
+
+    specify do
+      expect(
+        throwing(:foo)
+      ).to be_aliased_to(
+        throw_symbol(:foo)
+      ).with_description("throwing :foo")
+    end
+
+    specify do
+      expect(
+        a_block_yielding_control
+      ).to be_aliased_to(
+        yield_control
+      ).with_description("a block yielding control")
+    end
+
+    specify do
+      expect(
+        yielding_control
+      ).to be_aliased_to(
+        yield_control
+      ).with_description("yielding control")
+    end
+
+    specify do
+      expect(
+        a_block_yielding_with_no_args
+      ).to be_aliased_to(
+        yield_with_no_args
+      ).with_description("a block yielding with no args")
+    end
+
+    specify do
+      expect(
+        yielding_with_no_args
+      ).to be_aliased_to(
+        yield_with_no_args
+      ).with_description("yielding with no args")
+    end
+
+    specify do
+      expect(
+        a_block_yielding_with_args
+      ).to be_aliased_to(
+        yield_with_args
+      ).with_description("a block yielding with args")
+    end
+
+    specify do
+      expect(
+        yielding_with_args
+      ).to be_aliased_to(
+        yield_with_args
+      ).with_description("yielding with args")
+    end
+
+    specify do
+      expect(
+        a_block_yielding_successive_args
+      ).to be_aliased_to(
+        yield_successive_args
+      ).with_description("a block yielding successive args()")
+    end
+
+    specify do
+      expect(
+        yielding_successive_args
+      ).to be_aliased_to(
+        yield_successive_args
+      ).with_description("yielding successive args()")
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/all_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/all_spec.rb
new file mode 100644
index 0000000..6fea620
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/all_spec.rb
@@ -0,0 +1,212 @@
+module RSpec::Matchers::BuiltIn
+  RSpec.describe All do
+
+    it_behaves_like 'an RSpec matcher', :valid_value => ['A', 'A', 'A'], :invalid_value => ['A', 'A', 'B'], :disallows_negation => true do
+      let(:matcher) { all( eq('A') ) }
+    end
+
+    describe 'description' do
+      it 'provides a description' do
+        matcher = all( eq('A') )
+        expect(matcher.description).to eq 'all eq "A"'
+      end
+    end
+
+    context 'when single matcher is given' do
+
+      describe 'expect(...).to all(expected)' do
+
+        it 'can pass' do
+          expect(['A', 'A', 'A']).to all( eq('A') )
+        end
+
+        describe 'failure message' do
+
+          context 'when the matcher has single-line failure message' do
+            it 'returns the index of the failed object' do
+              expect {
+                expect(['A', 'A', 'A', 5, 'A']).to all( be_a(String) )
+              }.to fail_with(dedent <<-EOS)
+              |expected ["A", "A", "A", 5, "A"] to all be a kind of String
+              |
+              |   object at index 3 failed to match:
+              |      expected 5 to be a kind of String
+              EOS
+            end
+
+            it 'returns the indexes of all failed objects, not just the first one' do
+              expect {
+                expect(['A', 'A', 'A', 5, 6]).to all( be_a(String) )
+              }.to fail_with(dedent <<-EOS)
+              |expected ["A", "A", "A", 5, 6] to all be a kind of String
+              |
+              |   object at index 3 failed to match:
+              |      expected 5 to be a kind of String
+              |
+              |   object at index 4 failed to match:
+              |      expected 6 to be a kind of String
+              EOS
+            end
+          end
+
+
+          context 'when the matcher has multi-line failure message' do
+            it 'returns the index of the failed object' do
+              expect {
+                expect(['A', 'A', 'A', 'C', 'A']).to all( eq('A') )
+              }.to fail_with(dedent <<-EOS)
+              |expected ["A", "A", "A", "C", "A"] to all eq "A"
+              |
+              |   object at index 3 failed to match:
+              |      expected: "A"
+              |           got: "C"
+              |
+              |      (compared using ==)
+              EOS
+            end
+
+            it 'returns the indexes of all failed objects, not just the first one' do
+              expect {
+                expect(['A', 'B', 'A', 'C', 'A']).to all( eq('A') )
+              }.to fail_with(dedent <<-EOS)
+              |expected ["A", "B", "A", "C", "A"] to all eq "A"
+              |
+              |   object at index 1 failed to match:
+              |      expected: "A"
+              |           got: "B"
+              |
+              |      (compared using ==)
+              |
+              |   object at index 3 failed to match:
+              |      expected: "A"
+              |           got: "C"
+              |
+              |      (compared using ==)
+              EOS
+            end
+          end
+
+        end
+      end
+    end
+
+    context 'when composed matcher is given' do
+
+      describe 'expect(...).to all(expected)' do
+        it 'can pass' do
+          expect([3, 4, 7, 8]).to all( be_between(2, 5).or be_between(6, 9) )
+        end
+      end
+
+      describe 'failure message' do
+
+        context 'when a single object fails' do
+          it 'returns the index of the failed object for the composed matcher' do
+            expect {
+              expect([3, 4, 7, 28]).to all( be_between(2, 5).or be_between(6, 9) )
+            }.to fail_with(dedent <<-EOS)
+              |expected [3, 4, 7, 28] to all be between 2 and 5 (inclusive) or be between 6 and 9 (inclusive)
+              |
+              |   object at index 3 failed to match:
+              |      expected 28 to be between 2 and 5 (inclusive) or expected 28 to be between 6 and 9 (inclusive)
+            EOS
+          end
+        end
+
+        context 'when a multiple objects fails' do
+          it 'returns the indexes of the failed objects for the composed matcher, not just the first one' do
+            expect {
+              expect([3, 4, 27, 22]).to all( be_between(2, 5).or be_between(6, 9) )
+            }.to fail_with(dedent <<-EOS)
+              |expected [3, 4, 27, 22] to all be between 2 and 5 (inclusive) or be between 6 and 9 (inclusive)
+              |
+              |   object at index 2 failed to match:
+              |      expected 27 to be between 2 and 5 (inclusive) or expected 27 to be between 6 and 9 (inclusive)
+              |
+              |   object at index 3 failed to match:
+              |      expected 22 to be between 2 and 5 (inclusive) or expected 22 to be between 6 and 9 (inclusive)
+            EOS
+          end
+        end
+      end
+    end
+
+    shared_examples "making a copy" do |copy_method|
+      context "when making a copy via `#{copy_method}`" do
+
+        let(:base_matcher) { eq(3) }
+        let(:all_matcher) { all( base_matcher ) }
+        let(:copied_matcher) { all_matcher.__send__(copy_method) }
+
+        it "uses a copy of the base matcher" do
+          expect(copied_matcher).not_to equal(all_matcher)
+          expect(copied_matcher.matcher).not_to equal(base_matcher)
+          expect(copied_matcher.matcher).to be_a(base_matcher.class)
+          expect(copied_matcher.matcher.expected).to eq(3)
+        end
+
+        context 'when using a custom matcher' do
+
+          let(:base_matcher) { custom_include(3) }
+
+          it 'copies custom matchers properly so they can work even though they have singleton behavior' do
+            expect(copied_matcher).not_to equal(all_matcher)
+            expect(copied_matcher.matcher).not_to equal(base_matcher)
+            expect([[3]]).to copied_matcher
+            expect { expect([[4]]).to copied_matcher }.to fail_matching("expected [4]")
+          end
+
+        end
+
+      end
+    end
+
+    include_examples 'making a copy', :clone
+    include_examples 'making a copy', :dup
+
+    context "when using a matcher instance that memoizes state multiple times in a composed expression" do
+      it "works properly in spite of the memoization" do
+        expect {
+          expect(["foo", "bar", "a"]).to all( have_string_length(3) )
+        }.to fail
+      end
+
+      context "when passing a compound expression" do
+        it "works properly in spite of the memoization" do
+          expect {
+            expect(["foo", "bar", "a"]).to all( have_string_length(2).or have_string_length(3) )
+          }.to fail
+        end
+      end
+    end
+
+    context 'when the actual data does not define #each_with_index' do
+      let(:actual) { 5 }
+
+      it 'returns a failure message' do
+        expect {
+          expect(actual).to all(be_a(String))
+        }.to fail_with("expected #{actual.inspect} to all be a kind of String, but was not iterable")
+      end
+    end
+
+    context 'when the actual data does not include enumerable but defines #each_with_index' do
+      let(:actual) do
+        obj = Object.new
+        def obj.each_with_index(&block); [5].each_with_index { |o,i| yield(o,i) }; end
+        obj
+      end
+
+      it 'passes properly' do
+        expect(actual).to all(be_a(Integer))
+      end
+
+      it 'fails properly' do
+        expect {
+          expect(actual).to all(be_even)
+        }.to fail_with(/to all be even/)
+      end
+    end
+
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/base_matcher_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/base_matcher_spec.rb
new file mode 100644
index 0000000..b5cb4e6
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/base_matcher_spec.rb
@@ -0,0 +1,140 @@
+module RSpec::Matchers::BuiltIn
+  RSpec.describe BaseMatcher do
+    describe "#match_unless_raises" do
+      let(:matcher) do
+        Class.new(BaseMatcher).new
+      end
+
+      it "returns true if there are no errors" do
+        expect(matcher.match_unless_raises {}).to be_truthy
+      end
+
+      it "returns false if there is an error" do
+        expect(matcher.match_unless_raises { raise }).to be_falsey
+      end
+
+      it "returns false if the only submitted error is raised" do
+        expect(matcher.match_unless_raises(RuntimeError){ raise "foo" }).to be_falsey
+      end
+
+      it "returns false if any of several errors submitted is raised" do
+        expect(matcher.match_unless_raises(RuntimeError, ArgumentError, NameError) { raise "foo" }).to be_falsey
+        expect(matcher.match_unless_raises(RuntimeError, ArgumentError, NameError) { raise ArgumentError.new('') }).to be_falsey
+        expect(matcher.match_unless_raises(RuntimeError, ArgumentError, NameError) { raise NameError.new('') }).to be_falsey
+      end
+
+      it "re-raises any error other than one of those specified" do
+        expect do
+          matcher.match_unless_raises(ArgumentError){ raise "foo" }
+        end.to raise_error
+      end
+
+      it "stores the rescued exception for use in messages" do
+        matcher.match_unless_raises(RuntimeError){ raise "foo" }
+        expect(matcher.rescued_exception).to be_a(RuntimeError)
+        expect(matcher.rescued_exception.message).to eq("foo")
+      end
+
+    end
+
+    describe "#failure_message" do
+      context "when the parameter to .new is omitted" do
+        it "describes what was expected" do
+          matcher_class = Class.new(BaseMatcher) do
+            def name=(name)
+              @name = name
+            end
+
+            def match(expected, actual)
+              false
+            end
+          end
+
+          matcher = matcher_class.new
+          matcher.name = "be something"
+          matcher.matches?("foo")
+          expect(matcher.failure_message).to eq('expected "foo" to be something')
+        end
+      end
+    end
+
+    describe "#===" do
+      it "responds the same way as matches?" do
+        matcher = Class.new(BaseMatcher) do
+          def initialize(expected)
+            @expected = expected
+          end
+
+          def matches?(actual)
+            (@actual = actual) == @expected
+          end
+        end
+
+        expect(matcher.new(3).matches?(3)).to be_truthy
+        expect(matcher.new(3)).to be === 3
+
+        expect(matcher.new(3).matches?(4)).to be_falsey
+        expect(matcher.new(3)).not_to be === 4
+      end
+    end
+
+    describe "default failure message detection" do
+      def has_default_failure_messages?(matcher)
+        BaseMatcher::DefaultFailureMessages.has_default_failure_messages?(matcher)
+      end
+
+      shared_examples_for "detecting default failure message" do
+        context "that has no failure message overrides" do
+          it "indicates that it has default failure messages" do
+            matcher = build_matcher
+            expect(has_default_failure_messages?(matcher)).to be true
+          end
+        end
+
+        context "that overrides `failure_message`" do
+          it "indicates that it lacks default failure messages" do
+            matcher = build_matcher { def failure_message; end }
+            expect(has_default_failure_messages?(matcher)).to be false
+          end
+        end
+
+        context "that overrides `failure_message_when_negated`" do
+          it "indicates that it lacks default failure messages" do
+            matcher = build_matcher { def failure_message_when_negated; end }
+            expect(has_default_failure_messages?(matcher)).to be false
+          end
+        end
+      end
+
+      context "for a DSL-defined custom macher" do
+        include_examples "detecting default failure message" do
+          def build_matcher(&block)
+            definition = Proc.new do
+              match { }
+              module_exec(&block) if block
+            end
+
+            RSpec::Matchers::DSL::Matcher.new(:matcher_name, definition, self)
+          end
+        end
+      end
+
+      context "for a matcher that subclasses `BaseMatcher`" do
+        include_examples "detecting default failure message" do
+          def build_matcher(&block)
+            Class.new(RSpec::Matchers::BuiltIn::BaseMatcher, &block).new
+          end
+        end
+      end
+
+      context "for a custom matcher that lacks `failure_message_when_negated` (documented as an optional part of the matcher protocol" do
+        it "indicates that it lacks default failure messages" do
+          matcher = Class.new(RSpec::Matchers::BuiltIn::BaseMatcher) { undef failure_message_when_negated }.new
+
+          expect(RSpec::Support.is_a_matcher?(matcher)).to be true
+          expect(has_default_failure_messages?(matcher)).to be false
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/be_between_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/be_between_spec.rb
new file mode 100644
index 0000000..bb7f0ae
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/be_between_spec.rb
@@ -0,0 +1,157 @@
+module RSpec::Matchers::BuiltIn
+  RSpec.describe BeBetween do
+    class SizeMatters
+      include Comparable
+      attr :str
+      def <=>(other)
+        str.size <=> other.str.size
+      end
+      def initialize(str)
+        @str = str
+      end
+      def inspect
+        @str
+      end
+    end
+
+    shared_examples "be_between" do |mode|
+      it "passes if target is between min and max" do
+        expect(5).to matcher(1, 10)
+      end
+
+      it "fails if target is not between min and max" do
+        expect {
+          # It does not go to 11
+          expect(11).to matcher(1, 10)
+        }.to fail_with("expected 11 to be between 1 and 10 (#{mode})")
+      end
+
+      it "works with strings" do
+        expect("baz").to matcher("bar", "foo")
+
+        expect {
+          expect("foo").to matcher("bar", "baz")
+        }.to fail_with("expected \"foo\" to be between \"bar\" and \"baz\" (#{mode})")
+      end
+
+      it "works with other Comparable objects" do
+        expect(SizeMatters.new("--")).to matcher(SizeMatters.new("-"), SizeMatters.new("---"))
+
+        expect {
+          expect(SizeMatters.new("---")).to matcher(SizeMatters.new("-"), SizeMatters.new("--"))
+        }.to fail_with("expected --- to be between - and -- (#{mode})")
+      end
+    end
+
+    shared_examples "not_to be_between" do |mode|
+      it "passes if target is not between min and max" do
+        expect(11).not_to matcher(1, 10)
+      end
+
+      it "fails if target is between min and max" do
+        expect {
+          expect(5).not_to matcher(1, 10)
+        }.to fail_with("expected 5 not to be between 1 and 10 (#{mode})")
+      end
+    end
+
+    shared_examples "composing with other matchers" do |mode|
+      it "passes when the matchers both match" do
+        expect([nil, 3]).to include(matcher(2, 4), a_nil_value)
+      end
+
+      it "works with mixed types" do
+        expect(["baz", Math::PI]).to include(matcher(3.1, 3.2), matcher("bar", "foo"))
+
+        expect {
+          expect(["baz", 2.14]).to include(matcher(3.1, 3.2), matcher("bar", "foo") )
+        }.to fail_with("expected [\"baz\", 2.14] to include (a value between 3.1 and 3.2 (#{mode})) and (a value between \"bar\" and \"foo\" (#{mode}))")
+      end
+
+      it "provides a description" do
+        description = include(matcher(2, 4), an_instance_of(Float)).description
+        expect(description).to eq("include (a value between 2 and 4 (#{mode})) and (an instance of Float)")
+      end
+
+      it "fails with a clear error message when the matchers do not match" do
+        expect {
+          expect([nil, 1]).to include(matcher(2, 4), a_nil_value)
+        }.to fail_with("expected [nil, 1] to include (a value between 2 and 4 (#{mode})) and (a nil value)")
+      end
+    end
+
+    it_behaves_like "an RSpec matcher", :valid_value => (10), :invalid_value => (11) do
+      let(:matcher) { be_between(1, 10) }
+    end
+
+    describe "expect(...).to be_between(min, max) (inclusive)" do
+      it_behaves_like "be_between", :inclusive do
+        def matcher(min, max)
+          be_between(min, max)
+        end
+      end
+
+      it "is inclusive" do
+        expect(1).to be_between(1, 10)
+        expect(10).to be_between(1, 10)
+      end
+
+      it "indicates it was not comparable if it does not respond to `<=` and `>=`" do
+        expect {
+          expect(nil).to be_between(0, 10)
+        }.to fail_with("expected nil to be between 0 and 10 (inclusive), but it does not respond to `<=` and `>=`")
+      end
+    end
+
+    describe "expect(...).to be_between(min, max) (exclusive)" do
+      it_behaves_like "be_between", :exclusive do
+        def matcher(min, max)
+          be_between(min, max).exclusive
+        end
+      end
+
+      it "indicates it was not comparable if it does not respond to `<` and `>`" do
+        expect {
+          expect(nil).to be_between(0, 10).exclusive
+        }.to fail_with("expected nil to be between 0 and 10 (exclusive), but it does not respond to `<` and `>`")
+      end
+
+      it "is exclusive" do
+        expect { expect(1).to be_between(1, 10).exclusive }.to fail
+        expect { expect(10).to be_between(1, 10).exclusive }.to fail
+      end
+    end
+
+    describe "expect(...).not_to be_between(min, max) (inclusive)" do
+      it_behaves_like "not_to be_between", :inclusive do
+        def matcher(min, max)
+          be_between(min, max)
+        end
+      end
+    end
+
+    describe "expect(...).not_to be_between(min, max) (exclusive)" do
+      it_behaves_like "not_to be_between", :exclusive do
+        def matcher(min, max)
+          be_between(min, max).exclusive
+        end
+      end
+    end
+
+    describe "composing with other matchers (inclusive)" do
+      it_behaves_like "composing with other matchers", :inclusive do
+        def matcher(min, max)
+          a_value_between(min, max)
+        end
+      end
+    end
+
+    describe "composing with other matchers (exclusive)" do
+      it_behaves_like "composing with other matchers", :exclusive do
+        def matcher(min, max)
+          a_value_between(min, max).exclusive
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/be_instance_of_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/be_instance_of_spec.rb
new file mode 100644
index 0000000..f198acc
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/be_instance_of_spec.rb
@@ -0,0 +1,61 @@
+module RSpec
+  module Matchers
+    [:be_an_instance_of, :be_instance_of].each do |method|
+      RSpec.describe "expect(actual).to #{method}(expected)" do
+        it_behaves_like "an RSpec matcher", :valid_value => 5, :invalid_value => "a" do
+          let(:matcher) { send(method, Fixnum) }
+        end
+
+        it "passes if actual is instance of expected class" do
+          expect(5).to send(method, Fixnum)
+        end
+
+        it "fails if actual is instance of subclass of expected class" do
+          expect {
+            expect(5).to send(method, Numeric)
+          }.to fail_with(%Q{expected 5 to be an instance of Numeric})
+        end
+
+        it "fails with failure message for should unless actual is instance of expected class" do
+          expect {
+            expect("foo").to send(method, Array)
+          }.to fail_with(%Q{expected "foo" to be an instance of Array})
+        end
+
+        it "provides a description" do
+          matcher = be_an_instance_of(Fixnum)
+          matcher.matches?(Numeric)
+          expect(matcher.description).to eq "be an instance of Fixnum"
+        end
+
+        context "when expected provides an expanded inspect, e.g. AR::Base" do
+          let(:user_klass) do
+            Class.new do
+              def self.inspect
+                "User(id: integer, name: string)"
+              end
+            end
+          end
+
+          before { stub_const("User", user_klass) }
+
+          it "provides a description including only the class name" do
+            matcher = be_an_instance_of(User)
+            expect(matcher.description).to eq "be an instance of User"
+          end
+        end
+      end
+
+      RSpec.describe "expect(actual).not_to #{method}(expected)" do
+
+        it "fails with failure message for should_not if actual is instance of expected class" do
+          expect {
+            expect("foo").not_to send(method, String)
+          }.to fail_with(%Q{expected "foo" not to be an instance of String})
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/be_kind_of_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/be_kind_of_spec.rb
new file mode 100644
index 0000000..51bc227
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/be_kind_of_spec.rb
@@ -0,0 +1,39 @@
+module RSpec
+  module Matchers
+    [:be_a_kind_of, :be_kind_of].each do |method|
+      RSpec.describe "expect(actual).to #{method}(expected)" do
+        it_behaves_like "an RSpec matcher", :valid_value => 5, :invalid_value => "a" do
+          let(:matcher) { send(method, Fixnum) }
+        end
+
+        it "passes if actual is instance of expected class" do
+          expect(5).to send(method, Fixnum)
+        end
+
+        it "passes if actual is instance of subclass of expected class" do
+          expect(5).to send(method, Numeric)
+        end
+
+        it "fails with failure message for should unless actual is kind of expected class" do
+          expect {
+            expect("foo").to send(method, Array)
+          }.to fail_with(%Q{expected "foo" to be a kind of Array})
+        end
+
+        it "provides a description" do
+          matcher = be_a_kind_of(String)
+          matcher.matches?("this")
+          expect(matcher.description).to eq "be a kind of String"
+        end
+      end
+
+      RSpec.describe "expect(actual).not_to #{method}(expected)" do
+        it "fails with failure message for should_not if actual is kind of expected class" do
+          expect {
+            expect("foo").not_to send(method, String)
+          }.to fail_with(%Q{expected "foo" not to be a kind of String})
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/be_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/be_spec.rb
new file mode 100644
index 0000000..23948c4
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/be_spec.rb
@@ -0,0 +1,691 @@
+RSpec.describe "expect(...).to be_predicate" do
+  it "passes when actual returns true for :predicate?" do
+    actual = double("actual", :happy? => true)
+    expect(actual).to be_happy
+  end
+
+  it 'allows composable aliases to be defined' do
+    RSpec::Matchers.alias_matcher :a_user_who_is_happy, :be_happy
+    actual = double("actual", :happy? => true)
+    expect(actual).to a_user_who_is_happy
+    expect(a_user_who_is_happy.description).to eq("a user who is happy")
+
+    RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin
+    actual = double("actual", :admin? => true)
+    expect(actual).to a_user_who_is_an_admin
+    expect(a_user_who_is_an_admin.description).to eq("a user who is an admin")
+
+    RSpec::Matchers.alias_matcher :an_animal_that_is_a_canine, :be_a_canine
+    actual = double("actual", :canine? => true)
+    expect(actual).to an_animal_that_is_a_canine
+    expect(an_animal_that_is_a_canine.description).to eq("an animal that is a canine")
+  end
+
+  it 'composes gracefully' do
+    RSpec::Matchers.alias_matcher :a_happy_object, :be_happy
+    expect([
+      double,
+      double(:happy? => false),
+      double(:happy? => true),
+    ]).to include a_happy_object
+  end
+
+  it "passes when actual returns true for :predicates? (present tense)" do
+    actual = double("actual", :exists? => true, :exist? => true)
+    expect(actual).to be_exist
+  end
+
+  context "when actual returns false for :predicate?" do
+    it "fails when actual returns false for :predicate?" do
+      actual = double("actual", :happy? => false)
+      expect {
+        expect(actual).to be_happy
+      }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name=\"actual\">\.happy\?` to return true, got false/)
+    end
+
+    it "only calls :predicate? once" do
+      actual = double "actual", :happy? => false
+
+      expect(actual).to receive(:happy?).once
+      expect { expect(actual).to be_happy }.to fail
+    end
+  end
+
+  it "fails when actual returns nil for :predicate?" do
+    actual = double("actual", :happy? => nil)
+    expect {
+      expect(actual).to be_happy
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name=\"actual\">\.happy\?` to return true, got nil/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    expect {
+      expect(Object.new).to be_happy
+    }.to fail_matching("to respond to `happy?`")
+  end
+
+  it 'falls back to a present-tense form of the predicate when needed' do
+    mouth = Object.new
+    def mouth.frowns?(return_val); return_val; end
+
+    expect(mouth).to be_frown(true)
+    expect(mouth).not_to be_frown(false)
+
+    expect { expect(mouth).to be_frown(false) }.to fail
+    expect { expect(mouth).not_to be_frown(true) }.to fail
+  end
+
+  it 'fails when :predicate? is private' do
+    privately_happy = Class.new do
+      private
+        def happy?
+          true
+        end
+    end
+    expect { expect(privately_happy.new).to be_happy }.to fail_with(/private/)
+  end
+
+  it 'does not call :private_methods when the object publicly responds to the message' do
+    publicly_happy = double('happy')
+    expect(publicly_happy).to receive(:happy?) { true }
+    expect(publicly_happy).not_to receive(:private_methods)
+    expect(publicly_happy).to be_happy
+  end
+
+  it "fails on error other than NameError" do
+    actual = double("actual")
+    expect(actual).to receive(:foo?).and_raise("aaaah")
+    expect {
+      expect(actual).to be_foo
+    }.to raise_error(/aaaah/)
+  end
+
+  it 'raises an error when :predicate? exists but raises NameError' do
+    actual_class = Class.new do
+      def foo?
+        raise NameError, "aaaah"
+      end
+    end
+    expect {
+      expect(actual_class.new).to be_foo
+    }.to raise_error(NameError, /aaaah/)
+  end
+
+  it "fails on error other than NameError (with the present tense predicate)" do
+    actual = Object.new
+    expect(actual).to receive(:foos?).and_raise("aaaah")
+    expect {
+      expect(actual).to be_foo
+    }.to raise_error(/aaaah/)
+  end
+
+  it "does not support operator chaining like a basic `be` matcher does" do
+    matcher = be_happy
+    value = double(:happy? => false)
+    expect(matcher == value).to be false
+  end
+end
+
+RSpec.describe "expect(...).not_to be_predicate" do
+  it "passes when actual returns false for :sym?" do
+    actual = double("actual", :happy? => false)
+    expect(actual).not_to be_happy
+  end
+
+  it "passes when actual returns nil for :sym?" do
+    actual = double("actual", :happy? => nil)
+    expect(actual).not_to be_happy
+  end
+
+  it "fails when actual returns true for :sym?" do
+    actual = double("actual", :happy? => true)
+    expect {
+      expect(actual).not_to be_happy
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name=\"actual\">\.happy\?` to return false, got true/)
+  end
+
+  it "fails when actual does not respond to :sym?" do
+    expect {
+      expect(Object.new).not_to be_happy
+    }.to fail_matching("to respond to `happy?`")
+  end
+end
+
+RSpec.describe "expect(...).to be_predicate(*args)" do
+  it "passes when actual returns true for :predicate?(*args)" do
+    actual = double("actual")
+    expect(actual).to receive(:older_than?).with(3).and_return(true)
+    expect(actual).to be_older_than(3)
+  end
+
+  it "fails when actual returns false for :predicate?(*args)" do
+    actual = double("actual")
+    expect(actual).to receive(:older_than?).with(3).and_return(false)
+    expect {
+      expect(actual).to be_older_than(3)
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name="actual">.older_than\?\(3\)` to return true, got false/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    expect {
+      expect(Object.new).to be_older_than(3)
+    }.to fail_matching("to respond to `older_than?`")
+  end
+end
+
+RSpec.describe "expect(...).not_to be_predicate(*args)" do
+  it "passes when actual returns false for :predicate?(*args)" do
+    actual = double("actual")
+    expect(actual).to receive(:older_than?).with(3).and_return(false)
+    expect(actual).not_to be_older_than(3)
+  end
+
+  it "fails when actual returns true for :predicate?(*args)" do
+    actual = double("actual")
+    expect(actual).to receive(:older_than?).with(3).and_return(true)
+    expect {
+      expect(actual).not_to be_older_than(3)
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name="actual">.older_than\?\(3\)` to return false, got true/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    expect {
+      expect(Object.new).not_to be_older_than(3)
+    }.to fail_matching("to respond to `older_than?`")
+  end
+end
+
+RSpec.describe "expect(...).to be_predicate(&block)" do
+  it "passes when actual returns true for :predicate?(&block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:happy?).and_yield
+    expect(delegate).to receive(:check_happy).and_return(true)
+    expect(actual).to be_happy { delegate.check_happy }
+  end
+
+  it "fails when actual returns false for :predicate?(&block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:happy?).and_yield
+    expect(delegate).to receive(:check_happy).and_return(false)
+    expect {
+      expect(actual).to be_happy { delegate.check_happy }
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name=\"actual\">\.happy\?` to return true, got false/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    delegate = double("delegate", :check_happy => true)
+    expect {
+      expect(Object.new).to be_happy { delegate.check_happy }
+    }.to fail_matching("to respond to `happy?`")
+  end
+
+  it 'passes the block on to the present-tense predicate form' do
+    mouth = Object.new
+    def mouth.frowns?; yield; end
+
+    expect(mouth).to be_frown { true }
+    expect(mouth).not_to be_frown { false }
+  end
+
+  it 'works with a do..end block for either predicate form' do
+    mouth1 = Object.new
+    def mouth1.frown?; yield; end
+    mouth2 = Object.new
+    def mouth2.frowns?; yield; end
+
+    expect(mouth1).to be_frown do
+      true
+    end
+
+    expect(mouth1).not_to be_frown do
+      false
+    end
+
+    expect(mouth2).to be_frown do
+      true
+    end
+
+    expect(mouth2).not_to be_frown do
+      false
+    end
+  end
+
+  it 'prefers a { ... } block to a do/end block because it binds more tightly' do
+    mouth1 = Object.new
+    def mouth1.frown?; yield; end
+    mouth2 = Object.new
+    def mouth2.frowns?; yield; end
+
+    expect(mouth1).to be_frown { true } do
+      false
+    end
+
+    expect(mouth1).not_to be_frown { false } do
+      true
+    end
+
+    expect(mouth2).to be_frown { true } do
+      false
+    end
+
+    expect(mouth2).not_to be_frown { false } do
+      true
+    end
+  end
+end
+
+RSpec.describe "expect(...).not_to be_predicate(&block)" do
+  it "passes when actual returns false for :predicate?(&block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:happy?).and_yield
+    expect(delegate).to receive(:check_happy).and_return(false)
+    expect(actual).not_to be_happy { delegate.check_happy }
+  end
+
+  it "fails when actual returns true for :predicate?(&block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:happy?).and_yield
+    expect(delegate).to receive(:check_happy).and_return(true)
+    expect {
+      expect(actual).not_to be_happy { delegate.check_happy }
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name=\"actual\">\.happy\?` to return false, got true/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    delegate = double("delegate", :check_happy => true)
+    expect {
+      expect(Object.new).not_to be_happy { delegate.check_happy }
+    }.to fail_matching("to respond to `happy?`")
+  end
+end
+
+RSpec.describe "expect(...).to be_predicate(*args, &block)" do
+  it "passes when actual returns true for :predicate?(*args, &block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:older_than?).with(3).and_yield(3)
+    expect(delegate).to receive(:check_older_than).with(3).and_return(true)
+    expect(actual).to be_older_than(3) { |age| delegate.check_older_than(age) }
+  end
+
+  it "fails when actual returns false for :predicate?(*args, &block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:older_than?).with(3).and_yield(3)
+    expect(delegate).to receive(:check_older_than).with(3).and_return(false)
+    expect {
+      expect(actual).to be_older_than(3) { |age| delegate.check_older_than(age) }
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name=\"actual\">\.older_than\?\(3\)` to return true, got false/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    delegate = double("delegate", :check_older_than => true)
+    expect {
+      expect(Object.new).to be_older_than(3) { |age| delegate.check_older_than(age) }
+    }.to fail_matching("to respond to `older_than?`")
+  end
+end
+
+RSpec.describe "expect(...).not_to be_predicate(*args, &block)" do
+  it "passes when actual returns false for :predicate?(*args, &block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:older_than?).with(3).and_yield(3)
+    expect(delegate).to receive(:check_older_than).with(3).and_return(false)
+    expect(actual).not_to be_older_than(3) { |age| delegate.check_older_than(age) }
+  end
+
+  it "fails when actual returns true for :predicate?(*args, &block)" do
+    actual = double("actual")
+    delegate = double("delegate")
+    expect(actual).to receive(:older_than?).with(3).and_yield(3)
+    expect(delegate).to receive(:check_older_than).with(3).and_return(true)
+    expect {
+      expect(actual).not_to be_older_than(3) { |age| delegate.check_older_than(age) }
+    }.to fail_with(/expected `#<RSpec::Mocks::Double:0x[0-9a-f]+ @name="actual">.older_than\?\(3\)` to return false, got true/)
+  end
+
+  it "fails when actual does not respond to :predicate?" do
+    delegate = double("delegate", :check_older_than => true)
+    expect {
+      expect(Object.new).not_to be_older_than(3) { |age| delegate.check_older_than(age) }
+    }.to fail_matching("to respond to `older_than?`")
+  end
+end
+
+RSpec.describe "expect(...).to be_truthy" do
+  it "passes when actual equal?(true)" do
+    expect(true).to be_truthy
+  end
+
+  it "passes when actual is 1" do
+    expect(1).to be_truthy
+  end
+
+  it "fails when actual equal?(false)" do
+    expect {
+      expect(false).to be_truthy
+    }.to fail_with("expected: truthy value\n     got: false")
+  end
+end
+
+RSpec.describe "expect(...).to be_falsey" do
+  it "passes when actual equal?(false)" do
+    expect(false).to be_falsey
+  end
+
+  it "passes when actual equal?(nil)" do
+    expect(nil).to be_falsey
+  end
+
+  it "fails when actual equal?(true)" do
+    expect {
+      expect(true).to be_falsey
+    }.to fail_with("expected: falsey value\n     got: true")
+  end
+end
+
+RSpec.describe "expect(...).to be_falsy" do
+  it "passes when actual equal?(false)" do
+    expect(false).to be_falsy
+  end
+
+  it "passes when actual equal?(nil)" do
+    expect(nil).to be_falsy
+  end
+
+  it "fails when actual equal?(true)" do
+    expect {
+      expect(true).to be_falsy
+    }.to fail_with("expected: falsey value\n     got: true")
+  end
+end
+
+RSpec.describe "expect(...).to be_nil" do
+  it "passes when actual is nil" do
+    expect(nil).to be_nil
+  end
+
+  it "fails when actual is not nil" do
+    expect {
+      expect(:not_nil).to be_nil
+    }.to fail_with(/^expected: nil/)
+  end
+end
+
+RSpec.describe "expect(...).not_to be_nil" do
+  it "passes when actual is not nil" do
+    expect(:not_nil).not_to be_nil
+  end
+
+  it "fails when actual is nil" do
+    expect {
+      expect(nil).not_to be_nil
+    }.to fail_with(/^expected: not nil/)
+  end
+end
+
+RSpec.describe "expect(...).to be <" do
+  it "passes when < operator returns true" do
+    expect(3).to be < 4
+  end
+
+  it "fails when < operator returns false" do
+    expect {
+      expect(3).to be < 3
+    }.to fail_with("expected: < 3\n     got:   3")
+  end
+
+  it "describes itself" do
+    expect(be.<(4).description).to eq "be < 4"
+  end
+
+  it 'does not lie and say that it is equal to a number' do
+    matcher = (be < 3)
+    expect(5 == matcher).to be false
+  end
+end
+
+RSpec.describe "expect(...).to be <=" do
+  it "passes when <= operator returns true" do
+    expect(3).to be <= 4
+    expect(4).to be <= 4
+  end
+
+  it "fails when <= operator returns false" do
+    expect {
+      expect(3).to be <= 2
+    }.to fail_with("expected: <= 2\n     got:    3")
+  end
+end
+
+RSpec.describe "expect(...).to be >=" do
+  it "passes when >= operator returns true" do
+    expect(4).to be >= 4
+    expect(5).to be >= 4
+  end
+
+  it "fails when >= operator returns false" do
+    expect {
+      expect(3).to be >= 4
+    }.to fail_with("expected: >= 4\n     got:    3")
+  end
+end
+
+RSpec.describe "expect(...).to be >" do
+  it "passes when > operator returns true" do
+    expect(5).to be > 4
+  end
+
+  it "fails when > operator returns false" do
+    expect {
+      expect(3).to be > 4
+    }.to fail_with("expected: > 4\n     got:   3")
+  end
+end
+
+RSpec.describe "expect(...).to be ==" do
+  it "passes when == operator returns true" do
+    expect(5).to be == 5
+  end
+
+  it "fails when == operator returns false" do
+    expect {
+      expect(3).to be == 4
+    }.to fail_with("expected: == 4\n     got:    3")
+  end
+
+  it 'works when the target overrides `#send`' do
+    klass = Struct.new(:message) do
+      def send
+        :message_sent
+      end
+    end
+
+    msg_1 = klass.new("hello")
+    msg_2 = klass.new("hello")
+    expect(msg_1).to be == msg_2
+  end
+end
+
+RSpec.describe "expect(...).to be =~" do
+  it "passes when =~ operator returns true" do
+    expect("a string").to be =~ /str/
+  end
+
+  it "fails when =~ operator returns false" do
+    expect {
+      expect("a string").to be =~ /blah/
+    }.to fail_with(%Q|expected: =~ /blah/\n     got:    "a string"|)
+  end
+end
+
+RSpec.describe "should be =~", :uses_should do
+  it "passes when =~ operator returns true" do
+    "a string".should be =~ /str/
+  end
+
+  it "fails when =~ operator returns false" do
+    expect {
+      "a string".should be =~ /blah/
+    }.to fail_with(%Q|expected: =~ /blah/\n     got:    "a string"|)
+  end
+end
+
+RSpec.describe "expect(...).to be ===" do
+  it "passes when === operator returns true" do
+    expect(Hash).to be === Hash.new
+  end
+
+  it "fails when === operator returns false" do
+    expect {
+      expect(Hash).to be === "not a hash"
+    }.to fail_with(%[expected: === "not a hash"\n     got:     Hash])
+  end
+end
+
+RSpec.describe "expect(...).not_to with comparison operators" do
+  it "coaches user to stop using operators with expect().not_to with numerical comparison operators" do
+    expect {
+      expect(5).not_to be < 6
+    }.to fail_with("`expect(5).not_to be < 6` not only FAILED, it is a bit confusing.")
+
+    expect {
+      expect(5).not_to be <= 6
+    }.to fail_with("`expect(5).not_to be <= 6` not only FAILED, it is a bit confusing.")
+
+    expect {
+      expect(6).not_to be > 5
+    }.to fail_with("`expect(6).not_to be > 5` not only FAILED, it is a bit confusing.")
+
+    expect {
+      expect(6).not_to be >= 5
+    }.to fail_with("`expect(6).not_to be >= 5` not only FAILED, it is a bit confusing.")
+  end
+
+  it "coaches users to stop using negation with string comparison operators" do
+    expect {
+      expect("foo").not_to be > "bar"
+    }.to fail_with('`expect("foo").not_to be > "bar"` not only FAILED, it is a bit confusing.')
+  end
+end
+
+RSpec.describe "expect(...).not_to with equality operators" do
+  it "raises normal error with expect().not_to with equality operators" do
+    expect {
+      expect(6).not_to be == 6
+    }.to fail_with("`expect(6).not_to be == 6`")
+
+    expect {
+      expect(String).not_to be === "Hello"
+    }.to fail_with('`expect(String).not_to be === "Hello"`')
+  end
+end
+
+RSpec.describe "expect(...).to be" do
+  it "passes if actual is truthy" do
+    expect(true).to be
+    expect(1).to be
+  end
+
+  it "fails if actual is false" do
+    expect {
+      expect(false).to be
+    }.to fail_with("expected false to evaluate to true")
+  end
+
+  it "fails if actual is nil" do
+    expect {
+      expect(nil).to be
+    }.to fail_with("expected nil to evaluate to true")
+  end
+
+  it "describes itself" do
+    expect(be.description).to eq "be"
+  end
+end
+
+RSpec.describe "expect(...).not_to be" do
+  it "passes if actual is falsy" do
+    expect(false).not_to be
+    expect(nil).not_to be
+  end
+
+  it "fails on true" do
+    expect {
+      expect(true).not_to be
+    }.to fail_with("expected true to evaluate to false")
+  end
+end
+
+RSpec.describe "expect(...).to be(value)" do
+  it "delegates to equal" do
+    matcher = equal(5)
+    expect(self).to receive(:equal).with(5).and_return(matcher)
+    expect(5).to be(5)
+  end
+end
+
+RSpec.describe "expect(...).not_to be(value)" do
+  it "delegates to equal" do
+    matcher = equal(4)
+    expect(self).to receive(:equal).with(4).and_return(matcher)
+    expect(5).not_to be(4)
+  end
+end
+
+RSpec.describe "'expect(...).to be' with operator" do
+  it "includes 'be' in the description" do
+    expect((be > 6).description).to match(/be > 6/)
+    expect((be >= 6).description).to match(/be >= 6/)
+    expect((be <= 6).description).to match(/be <= 6/)
+    expect((be < 6).description).to match(/be < 6/)
+  end
+end
+
+
+RSpec.describe "arbitrary predicate with DelegateClass" do
+  it "accesses methods defined in the delegating class (LH[#48])" do
+    require 'delegate'
+    class ArrayDelegate < DelegateClass(Array)
+      def initialize(array)
+        @internal_array = array
+        super(@internal_array)
+      end
+
+      def large?
+        @internal_array.size >= 5
+      end
+    end
+
+    delegate = ArrayDelegate.new([1,2,3,4,5,6])
+    expect(delegate).to be_large
+  end
+end
+
+RSpec.describe "be_a, be_an" do
+  it "passes when class matches" do
+    expect("foobar").to be_a(String)
+    expect([1,2,3]).to be_an(Array)
+  end
+
+  it "fails when class does not match" do
+    expect("foobar").not_to be_a(Hash)
+    expect([1,2,3]).not_to be_an(Integer)
+  end
+end
+
+RSpec.describe "be_an_instance_of" do
+  it "passes when direct class matches" do
+    expect(5).to be_an_instance_of(Fixnum)
+  end
+
+  it "fails when class is higher up hierarchy" do
+    expect(5).not_to be_an_instance_of(Numeric)
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/be_within_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/be_within_spec.rb
new file mode 100644
index 0000000..72ca624
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/be_within_spec.rb
@@ -0,0 +1,139 @@
+module RSpec
+  module Matchers
+    RSpec.describe "expect(actual).to be_within(delta).of(expected)" do
+      it_behaves_like "an RSpec matcher", :valid_value => 5, :invalid_value => -5 do
+        let(:matcher) { be_within(2).of(4.0) }
+      end
+
+      it "passes when actual == expected" do
+        expect(5.0).to be_within(0.5).of(5.0)
+      end
+
+      it "passes when actual < (expected + delta)" do
+        expect(5.49).to be_within(0.5).of(5.0)
+      end
+
+      it "passes when actual > (expected - delta)" do
+        expect(4.51).to be_within(0.5).of(5.0)
+      end
+
+      it "passes when actual == (expected - delta)" do
+        expect(4.5).to be_within(0.5).of(5.0)
+      end
+
+      it "passes when actual == (expected + delta)" do
+        expect(5.5).to be_within(0.5).of(5.0)
+      end
+
+      it "passes with integer arguments that are near each other" do
+        expect(1.0001).to be_within(5).percent_of(1)
+      end
+
+      it "passes with negative arguments" do
+        expect(-1.0001).to be_within(5).percent_of(-1)
+      end
+
+      it "fails when actual < (expected - delta)" do
+        expect {
+          expect(4.49).to be_within(0.5).of(5.0)
+        }.to fail_with("expected 4.49 to be within 0.5 of 5.0")
+      end
+
+      it "fails when actual > (expected + delta)" do
+        expect {
+          expect(5.51).to be_within(0.5).of(5.0)
+        }.to fail_with("expected 5.51 to be within 0.5 of 5.0")
+      end
+
+      it "works with Time" do
+        expect(Time.now).to be_within(0.1).of(Time.now)
+      end
+
+      it "provides a description" do
+        matcher = be_within(0.5).of(5.0)
+        matcher.matches?(5.1)
+        expect(matcher.description).to eq "be within 0.5 of 5.0"
+      end
+
+      it "raises an error if no expected value is given" do
+        expect {
+          expect(5.1).to be_within(0.5)
+        }.to raise_error(ArgumentError, /must set an expected value using #of/)
+      end
+
+      it "fails if the actual is not numeric" do
+        expect {
+          expect(nil).to be_within(0.1).of(0)
+        }.to fail_with("expected nil to be within 0.1 of 0, but it could not be treated as a numeric value")
+      end
+    end
+
+    RSpec.describe "expect(actual).to be_within(delta).percent_of(expected)" do
+      it "passes when actual is within the given percent variance" do
+        expect(9.0).to be_within(10).percent_of(10.0)
+        expect(10.0).to be_within(10).percent_of(10.0)
+        expect(11.0).to be_within(10).percent_of(10.0)
+      end
+
+      it "fails when actual is outside the given percent variance" do
+        expect {
+          expect(8.9).to be_within(10).percent_of(10.0)
+        }.to fail_with("expected 8.9 to be within 10% of 10.0")
+
+        expect {
+          expect(11.1).to be_within(10).percent_of(10.0)
+        }.to fail_with("expected 11.1 to be within 10% of 10.0")
+      end
+
+      it "provides a description" do
+        matcher = be_within(0.5).percent_of(5.0)
+        matcher.matches?(5.1)
+        expect(matcher.description).to eq "be within 0.5% of 5.0"
+      end
+    end
+
+    RSpec.describe "expect(actual).not_to be_within(delta).of(expected)" do
+      it "passes when actual < (expected - delta)" do
+        expect(4.49).not_to be_within(0.5).of(5.0)
+      end
+
+      it "passes when actual > (expected + delta)" do
+        expect(5.51).not_to be_within(0.5).of(5.0)
+      end
+
+      it "fails when actual == expected" do
+        expect {
+          expect(5.0).not_to be_within(0.5).of(5.0)
+        }.to fail_with("expected 5.0 not to be within 0.5 of 5.0")
+      end
+
+      it "fails when actual < (expected + delta)" do
+        expect {
+          expect(5.49).not_to be_within(0.5).of(5.0)
+        }.to fail_with("expected 5.49 not to be within 0.5 of 5.0")
+      end
+
+      it "fails when actual > (expected - delta)" do
+        expect {
+          expect(4.51).not_to be_within(0.5).of(5.0)
+        }.to fail_with("expected 4.51 not to be within 0.5 of 5.0")
+      end
+
+      it "fails when actual == (expected - delta)" do
+        expect {
+          expect(4.5).not_to be_within(0.5).of(5.0)
+        }.to fail_with("expected 4.5 not to be within 0.5 of 5.0")
+      end
+
+      it "fails when actual == (expected + delta)" do
+        expect {
+          expect(5.5).not_to be_within(0.5).of(5.0)
+        }.to fail_with("expected 5.5 not to be within 0.5 of 5.0")
+      end
+
+      it "passes if the actual is not numeric" do
+        expect(nil).not_to be_within(0.1).of(0)
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/change_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/change_spec.rb
new file mode 100644
index 0000000..c58e3cb
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/change_spec.rb
@@ -0,0 +1,829 @@
+class SomethingExpected
+  attr_accessor :some_value
+end
+
+RSpec.describe "expect { ... }.to change(actual, message)" do
+  context "with a numeric value" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = 5
+    end
+
+    it "passes when actual is modified by the block" do
+      expect {@instance.some_value = 6.0}.to change(@instance, :some_value)
+    end
+
+    it "fails when actual is not modified by the block" do
+      expect do
+        expect {}.to change(@instance, :some_value)
+      end.to fail_with("expected #some_value to have changed, but is still 5")
+    end
+
+    it "provides a #description" do
+      expect(change(@instance, :some_value).description).to eq "change #some_value"
+    end
+  end
+
+  it "can specify the change of a variable's class" do
+    val = nil
+
+    expect {
+      val = 42
+    }.to change { val.class }.from(NilClass).to(Fixnum)
+
+    expect {
+      expect {
+        val = "string"
+      }.to change { val.class }.from(Fixnum).to(NilClass)
+    }.to fail_with(/but is now String/)
+  end
+
+  context "with boolean values" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = true
+    end
+
+    it "passes when actual is modified by the block" do
+      expect {@instance.some_value = false}.to change(@instance, :some_value)
+    end
+
+    it "fails when actual is not modified by the block" do
+      expect do
+        expect {}.to change(@instance, :some_value)
+      end.to fail_with("expected #some_value to have changed, but is still true")
+    end
+  end
+
+  context "with an IO stream" do
+    it "fails when the stream does not change" do
+      expect {
+        k = STDOUT
+        expect { }.to change { k }
+      }.to fail_with(/expected result to have changed/)
+    end
+  end
+
+  context "with nil value" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = nil
+    end
+
+    it "passes when actual is modified by the block" do
+      expect {@instance.some_value = false}.to change(@instance, :some_value)
+    end
+
+    it "fails when actual is not modified by the block" do
+      expect do
+        expect {}.to change(@instance, :some_value)
+      end.to fail_with("expected #some_value to have changed, but is still nil")
+    end
+  end
+
+  context "with an array" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = []
+    end
+
+    it "passes when actual is modified by the block" do
+      expect {@instance.some_value << 1}.to change(@instance, :some_value)
+    end
+
+    it "fails when a predicate on the actual fails" do
+      expect do
+        expect {@instance.some_value << 1}.to change { @instance.some_value }.to be_empty
+      end.to fail_with(/result to have changed to/)
+    end
+
+    it "passes when a predicate on the actual passes" do
+      @instance.some_value = [1]
+      expect {@instance.some_value.pop}.to change { @instance.some_value }.to be_empty
+    end
+
+    it "fails when actual is not modified by the block" do
+      expect do
+        expect {}.to change(@instance, :some_value)
+      end.to fail_with("expected #some_value to have changed, but is still []")
+    end
+  end
+
+  context "with a hash" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = {:a => 'a'}
+    end
+
+    it "passes when actual is modified by the block" do
+      expect {@instance.some_value[:a] = 'A'}.to change(@instance, :some_value)
+    end
+
+    it "fails when actual is not modified by the block" do
+      expect do
+        expect {}.to change(@instance, :some_value)
+      end.to fail
+    end
+  end
+
+  context "with a string" do
+    it "passes when actual is modified by the block" do
+      string = "ab"
+      expect { string << "c" }.to change { string }
+    end
+
+    it 'fails when actual is not modified by the block' do
+      string = "ab"
+      expect {
+        expect { }.to change { string }
+      }.to fail_with(/to have changed/)
+    end
+  end
+
+  context "with an arbitrary enumerable" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = Class.new do
+        include Enumerable
+
+        attr_reader :elements
+
+        def initialize(*elements)
+          @elements = elements.dup
+        end
+
+        def <<(element)
+          elements << element
+        end
+
+        def dup
+          self.class.new(*elements)
+        end
+
+        def ==(other)
+          elements == other.elements
+        end
+      end.new
+    end
+
+    it "passes when actual is modified by the block" do
+      expect {@instance.some_value << 1}.to change(@instance, :some_value)
+    end
+
+    it "fails when actual is not modified by the block" do
+      expect do
+        expect {}.to change(@instance, :some_value)
+      end.to fail_with(/^expected #some_value to have changed, but is still/)
+    end
+  end
+
+  context "with a missing message" do
+    it "fails with an ArgumentError" do
+      expect do
+        expect {}.to change(:receiver)
+      end.to raise_error(ArgumentError, /^`change` requires either an object and message/)
+    end
+  end
+end
+
+RSpec.describe "expect { ... }.not_to change(actual, message)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when actual is not modified by the block" do
+    expect { }.not_to change(@instance, :some_value)
+  end
+
+  it "fails when actual is not modified by the block" do
+    expect do
+      expect {@instance.some_value = 6}.not_to change(@instance, :some_value)
+    end.to fail_with("expected #some_value not to have changed, but did change from 5 to 6")
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }" do
+
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when actual is modified by the block" do
+    expect {@instance.some_value = 6}.to change { @instance.some_value }
+  end
+
+  it "fails when actual is not modified by the block" do
+    expect do
+      expect {}.to change{ @instance.some_value }
+    end.to fail_with("expected result to have changed, but is still 5")
+  end
+
+  it "warns if passed a block using do/end instead of {}" do
+    expect do
+      expect {}.to change do; end
+    end.to raise_error(SyntaxError, /block passed to the `change` matcher/)
+  end
+
+  it "provides a #description" do
+    expect(change { @instance.some_value }.description).to eq "change result"
+  end
+
+  context "with an IO stream" do
+    it "passes when the stream does not change" do
+      k = STDOUT
+      expect { }.not_to change { k }
+    end
+  end
+end
+
+RSpec.describe "expect { ... }.not_to change { block }" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when actual is modified by the block" do
+    expect {}.not_to change{ @instance.some_value }
+  end
+
+  it "fails when actual is not modified by the block" do
+    expect do
+      expect {@instance.some_value = 6}.not_to change { @instance.some_value }
+    end.to fail_with("expected result not to have changed, but did change from 5 to 6")
+  end
+
+  it "warns if passed a block using do/end instead of {}" do
+    expect do
+      expect {}.not_to change do; end
+    end.to raise_error(SyntaxError, /block passed to the `change` matcher/)
+  end
+end
+
+
+RSpec.describe "expect { ... }.not_to change { }.from" do
+  context 'when the value starts at the from value' do
+    it 'passes when the value does not change' do
+      k = 5
+      expect { }.not_to change { k }.from(5)
+    end
+
+    it 'fails when the value does change' do
+      expect {
+        k = 5
+        expect { k += 1 }.not_to change { k }.from(5)
+      }.to fail_with(/but did change from 5 to 6/)
+    end
+  end
+
+  context 'when the value starts at a different value' do
+    it 'fails when the value does not change' do
+      expect {
+        k = 6
+        expect { }.not_to change { k }.from(5)
+      }.to fail_with(/expected result to have initially been 5/)
+    end
+
+    it 'fails when the value does change' do
+      expect {
+        k = 6
+        expect { k += 1 }.not_to change { k }.from(5)
+      }.to fail_with(/expected result to have initially been 5/)
+    end
+  end
+end
+
+RSpec.describe "expect { ... }.not_to change { }.to" do
+  it 'is not supported' do
+    expect {
+      expect { }.not_to change { }.to(3)
+    }.to raise_error(NotImplementedError)
+  end
+
+  it 'is not supported when it comes after `from`' do
+    expect {
+      expect { }.not_to change { }.from(nil).to(3)
+    }.to raise_error(NotImplementedError)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to change { }.by" do
+  it 'is not supported' do
+    expect {
+      expect { }.not_to change { }.by(3)
+    }.to raise_error(NotImplementedError)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to change { }.by_at_least" do
+  it 'is not supported' do
+    expect {
+      expect { }.not_to change { }.by_at_least(3)
+    }.to raise_error(NotImplementedError)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to change { }.by_at_most" do
+  it 'is not supported' do
+    expect {
+      expect { }.not_to change { }.by_at_most(3)
+    }.to raise_error(NotImplementedError)
+  end
+end
+
+RSpec.describe "expect { ... }.to change(actual, message).by(expected)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when attribute is changed by expected amount" do
+    expect { @instance.some_value += 1 }.to change(@instance, :some_value).by(1)
+  end
+
+  it "passes when attribute is not changed and expected amount is 0" do
+    expect { @instance.some_value += 0 }.to change(@instance, :some_value).by(0)
+  end
+
+  it "fails when the attribute is changed by unexpected amount" do
+    expect do
+      expect { @instance.some_value += 2 }.to change(@instance, :some_value).by(1)
+    end.to fail_with("expected #some_value to have changed by 1, but was changed by 2")
+  end
+
+  it "fails when the attribute is changed by unexpected amount in the opposite direction" do
+    expect do
+      expect { @instance.some_value -= 1 }.to change(@instance, :some_value).by(1)
+    end.to fail_with("expected #some_value to have changed by 1, but was changed by -1")
+  end
+
+  it "provides a #description" do
+    expect(change(@instance, :some_value).by(3).description).to eq "change #some_value by 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }.by(expected)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when attribute is changed by expected amount" do
+    expect { @instance.some_value += 1 }.to change{@instance.some_value}.by(1)
+  end
+
+  it "fails when the attribute is changed by unexpected amount" do
+    expect do
+      expect { @instance.some_value += 2 }.to change{@instance.some_value}.by(1)
+    end.to fail_with("expected result to have changed by 1, but was changed by 2")
+  end
+
+  it "fails when the attribute is changed by unexpected amount in the opposite direction" do
+    expect do
+      expect { @instance.some_value -= 1 }.to change{@instance.some_value}.by(1)
+    end.to fail_with("expected result to have changed by 1, but was changed by -1")
+  end
+
+  it "provides a #description" do
+    expect(change { @instance.some_value }.by(3).description).to eq "change result by 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change(actual, message).by_at_least(expected)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when attribute is changed by greater than the expected amount" do
+    expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_least(1)
+  end
+
+  it "passes when attribute is changed by the expected amount" do
+    expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_least(2)
+  end
+
+  it "fails when the attribute is changed by less than the expected amount" do
+    expect do
+      expect { @instance.some_value += 1 }.to change(@instance, :some_value).by_at_least(2)
+    end.to fail_with("expected #some_value to have changed by at least 2, but was changed by 1")
+  end
+
+  it "provides a #description" do
+    expect(change(@instance, :some_value).by_at_least(3).description).to eq "change #some_value by at least 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }.by_at_least(expected)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when attribute is changed by greater than expected amount" do
+    expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_least(1)
+  end
+
+  it "passes when attribute is changed by the expected amount" do
+    expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_least(2)
+  end
+
+  it "fails when the attribute is changed by less than the unexpected amount" do
+    expect do
+      expect { @instance.some_value += 1 }.to change{@instance.some_value}.by_at_least(2)
+    end.to fail_with("expected result to have changed by at least 2, but was changed by 1")
+  end
+
+  it "provides a #description" do
+    expect(change { @instance.some_value }.by_at_least(3).description).to eq "change result by at least 3"
+  end
+end
+
+
+RSpec.describe "expect { ... }.to change(actual, message).by_at_most(expected)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when attribute is changed by less than the expected amount" do
+    expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_most(3)
+  end
+
+  it "passes when attribute is changed by the expected amount" do
+    expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_most(2)
+  end
+
+  it "fails when the attribute is changed by greater than the expected amount" do
+    expect do
+      expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_most(1)
+    end.to fail_with("expected #some_value to have changed by at most 1, but was changed by 2")
+  end
+
+  it "provides a #description" do
+    expect(change(@instance, :some_value).by_at_most(3).description).to eq "change #some_value by at most 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }.by_at_most(expected)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 5
+  end
+
+  it "passes when attribute is changed by less than expected amount" do
+    expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_most(3)
+  end
+
+  it "passes when attribute is changed by the expected amount" do
+    expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_most(2)
+  end
+
+  it "fails when the attribute is changed by greater than the unexpected amount" do
+    expect do
+      expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_most(1)
+    end.to fail_with("expected result to have changed by at most 1, but was changed by 2")
+  end
+
+  it "provides a #description" do
+    expect(change { @instance.some_value }.by_at_most(3).description).to eq "change result by at most 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change(actual, message).from(old)" do
+  context "with boolean values" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = true
+    end
+
+    it "passes when attribute is == to expected value before executing block" do
+      expect { @instance.some_value = false }.to change(@instance, :some_value).from(true)
+    end
+
+    it "fails when attribute is not == to expected value before executing block" do
+      expect do
+        expect { @instance.some_value = 'foo' }.to change(@instance, :some_value).from(false)
+      end.to fail_with("expected #some_value to have initially been false, but was true")
+    end
+  end
+  context "with non-boolean values" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = 'string'
+    end
+
+    it "passes when attribute matches expected value before executing block" do
+      expect { @instance.some_value = "astring" }.to change(@instance, :some_value).from("string")
+    end
+
+    it "fails when attribute does not match expected value before executing block" do
+      expect do
+        expect { @instance.some_value = "knot" }.to change(@instance, :some_value).from("cat")
+      end.to fail_with("expected #some_value to have initially been \"cat\", but was \"string\"")
+    end
+
+    it "provides a #description" do
+      expect(change(@instance, :some_value).from(3).description).to eq "change #some_value from 3"
+    end
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }.from(old)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 'string'
+  end
+
+  it "passes when attribute matches expected value before executing block" do
+    expect { @instance.some_value = "astring" }.to change{@instance.some_value}.from("string")
+  end
+
+  it "fails when attribute does not match expected value before executing block" do
+    expect do
+      expect { @instance.some_value = "knot" }.to change{@instance.some_value}.from("cat")
+    end.to fail_with("expected result to have initially been \"cat\", but was \"string\"")
+  end
+
+  it "fails when attribute does not change" do
+    expect do
+      expect { }.to change { @instance.some_value }.from("string")
+    end.to fail_with('expected result to have changed from "string", but did not change')
+  end
+
+  it "provides a #description" do
+    expect(change { }.from(3).description).to eq "change result from 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change(actual, message).to(new)" do
+  context "with boolean values" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = true
+    end
+
+    it "passes when attribute is == to expected value after executing block" do
+      expect { @instance.some_value = false }.to change(@instance, :some_value).to(false)
+    end
+
+    it "fails when attribute is not == to expected value after executing block" do
+      expect do
+        expect { @instance.some_value = 1 }.to change(@instance, :some_value).from(true).to(false)
+      end.to fail_with("expected #some_value to have changed to false, but is now 1")
+    end
+  end
+
+  context "with non-boolean values" do
+    before(:example) do
+      @instance = SomethingExpected.new
+      @instance.some_value = 'string'
+    end
+
+    it "passes when attribute matches expected value after executing block" do
+      expect { @instance.some_value = "cat" }.to change(@instance, :some_value).to("cat")
+    end
+
+    it "fails when attribute does not match expected value after executing block" do
+      expect do
+        expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("string").to("dog")
+      end.to fail_with("expected #some_value to have changed to \"dog\", but is now \"cat\"")
+    end
+
+    it "fails with a clear message when it ends with the right value but did not change" do
+      expect {
+        expect { }.to change(@instance, :some_value).to("string")
+      }.to fail_with('expected #some_value to have changed to "string", but did not change')
+    end
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }.to(new)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 'string'
+  end
+
+  it "passes when attribute matches expected value after executing block" do
+    expect { @instance.some_value = "cat" }.to change{@instance.some_value}.to("cat")
+  end
+
+  it "fails when attribute does not match expected value after executing block" do
+    expect do
+      expect { @instance.some_value = "cat" }.to change{@instance.some_value}.from("string").to("dog")
+    end.to fail_with("expected result to have changed to \"dog\", but is now \"cat\"")
+  end
+
+  it "provides a #description" do
+    expect(change { }.to(3).description).to eq "change result to 3"
+  end
+end
+
+RSpec.describe "expect { ... }.to change(actual, message).from(old).to(new)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 'string'
+  end
+
+  it "passes when #to comes before #from" do
+    expect { @instance.some_value = "cat" }.to change(@instance, :some_value).to("cat").from("string")
+  end
+
+  it "passes when #from comes before #to" do
+    expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("string").to("cat")
+  end
+
+  it "shows the correct messaging when #after and #to are different" do
+    expect do
+      expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("string").to("dog")
+    end.to fail_with("expected #some_value to have changed to \"dog\", but is now \"cat\"")
+  end
+
+  it "shows the correct messaging when #before and #from are different" do
+    expect do
+      expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("not_string").to("cat")
+    end.to fail_with("expected #some_value to have initially been \"not_string\", but was \"string\"")
+  end
+end
+
+RSpec.describe "expect { ... }.to change { block }.from(old).to(new)" do
+  before(:example) do
+    @instance = SomethingExpected.new
+    @instance.some_value = 'string'
+  end
+
+  context "when #to comes before #from" do
+    it "passes" do
+      expect { @instance.some_value = "cat" }.to change{@instance.some_value}.to("cat").from("string")
+    end
+
+    it "provides a #description" do
+      expect(change { }.to(1).from(3).description).to eq "change result to 1 from 3"
+    end
+  end
+
+  context "when #from comes before #to" do
+    it "passes" do
+      expect { @instance.some_value = "cat" }.to change{@instance.some_value}.from("string").to("cat")
+    end
+
+    it "provides a #description" do
+      expect(change { }.from(1).to(3).description).to eq "change result from 1 to 3"
+    end
+  end
+end
+
+RSpec.describe "Composing a matcher with `change`" do
+  describe "expect { ... }.to change { ... }" do
+    context ".from(matcher).to(matcher)" do
+      it 'passes when the matchers match the from and to values' do
+        k = 0.51
+        expect { k += 1 }.to change { k }.
+          from( a_value_within(0.1).of(0.5) ).
+          to( a_value_within(0.1).of(1.5) )
+      end
+
+      it 'fails with a clear message when the `from` does not match' do
+        expect {
+          k = 0.51
+          expect { k += 1 }.to change { k }.
+            from( a_value_within(0.1).of(0.7) ).
+            to( a_value_within(0.1).of(1.5) )
+        }.to fail_with(/expected result to have initially been a value within 0.1 of 0.7, but was 0.51/)
+      end
+
+      it 'fails with a clear message when the `to` does not match' do
+        expect {
+          k = 0.51
+          expect { k += 1 }.to change { k }.
+            from( a_value_within(0.1).of(0.5) ).
+            to( a_value_within(0.1).of(2.5) )
+        }.to fail_with(/expected result to have changed to a value within 0.1 of 2.5, but is now 1.51/)
+      end
+
+      it 'provides a description' do
+        expect(change(nil, :foo).
+          from( a_value_within(0.1).of(0.5) ).
+          to( a_value_within(0.1).of(1.5) ).description
+        ).to eq("change #foo from a value within 0.1 of 0.5 to a value within 0.1 of 1.5")
+      end
+    end
+
+    context ".to(matcher).from(matcher)" do
+      it 'passes when the matchers match the from and to values' do
+        k = 0.51
+        expect { k += 1 }.to change { k }.
+          to( a_value_within(0.1).of(1.5) ).
+          from( a_value_within(0.1).of(0.5) )
+      end
+
+      it 'fails with a clear message when the `from` does not match' do
+        expect {
+          k = 0.51
+          expect { k += 1 }.to change { k }.
+            to( a_value_within(0.1).of(1.5) ).
+            from( a_value_within(0.1).of(0.7) )
+        }.to fail_with(/expected result to have initially been a value within 0.1 of 0.7, but was 0.51/)
+      end
+
+      it 'fails with a clear message when the `to` does not match' do
+        expect {
+          k = 0.51
+          expect { k += 1 }.to change { k }.
+            to( a_value_within(0.1).of(2.5) ).
+            from( a_value_within(0.1).of(0.5) )
+        }.to fail_with(/expected result to have changed to a value within 0.1 of 2.5, but is now 1.51/)
+      end
+
+      it 'provides a description' do
+        expect(change(nil, :foo).
+          to( a_value_within(0.1).of(0.5) ).
+          from( a_value_within(0.1).of(1.5) ).description
+        ).to eq("change #foo to a value within 0.1 of 0.5 from a value within 0.1 of 1.5")
+      end
+    end
+
+    context ".by(matcher)" do
+      it "passes when the matcher matches" do
+        k = 0.5
+        expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1) )
+      end
+
+      it 'fails with a clear message when the `by` does not match' do
+        expect {
+          k = 0.5
+          expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(0.5) )
+        }.to fail_with(/expected result to have changed by a value within 0.1 of 0.5, but was changed by 1.05/)
+      end
+
+      it 'provides a description' do
+        expect(change(nil, :foo).
+          by( a_value_within(0.1).of(0.5) ).description
+        ).to eq("change #foo by a value within 0.1 of 0.5")
+      end
+    end
+  end
+
+  describe "expect { ... }.not_to change { ... }.from(matcher).to(matcher)" do
+    it 'passes when the matcher matches the `from` value and it does not change' do
+      k = 0.51
+      expect { }.not_to change { k }.from( a_value_within(0.1).of(0.5) )
+    end
+
+    it 'fails with a clear message when the `from` matcher does not match' do
+      expect {
+        k = 0.51
+        expect { }.not_to change { k }.from( a_value_within(0.1).of(1.5) )
+      }.to fail_with(/expected result to have initially been a value within 0.1 of 1.5, but was 0.51/)
+    end
+  end
+end
+
+RSpec.describe RSpec::Matchers::BuiltIn::Change do
+  it "works when the receiver has implemented #send" do
+    @instance = SomethingExpected.new
+    @instance.some_value = "string"
+    def @instance.send(*args); raise "DOH! Library developers shouldn't use #send!" end
+
+    expect {
+      expect { @instance.some_value = "cat" }.to change(@instance, :some_value)
+    }.not_to raise_error
+  end
+
+  k = 1
+  before { k = 1 }
+  it_behaves_like "an RSpec matcher", :valid_value => lambda { k += 1 },
+                                      :invalid_value => lambda { } do
+    let(:matcher) { change { k } }
+  end
+end
+
+RSpec.describe RSpec::Matchers::BuiltIn::ChangeRelatively do
+  k = 0
+  before { k = 0 }
+  it_behaves_like "an RSpec matcher", :valid_value => lambda { k += 1 },
+                                      :invalid_value => lambda { k += 2 },
+                                      :disallows_negation => true do
+    let(:matcher) { change { k }.by(1) }
+  end
+end
+
+RSpec.describe RSpec::Matchers::BuiltIn::ChangeFromValue do
+  k = 0
+  before { k = 0 }
+  it_behaves_like "an RSpec matcher", :valid_value => lambda { k += 1 },
+                                      :invalid_value => lambda { } do
+    let(:matcher) { change { k }.from(0) }
+  end
+end
+
+RSpec.describe RSpec::Matchers::BuiltIn::ChangeToValue do
+  k = 0
+  before { k = 0 }
+  it_behaves_like "an RSpec matcher", :valid_value => lambda { k = 2 },
+                                      :invalid_value => lambda { k = 3 },
+                                      :disallows_negation => true do
+    let(:matcher) { change { k }.to(2) }
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/compound_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/compound_spec.rb
new file mode 100644
index 0000000..f9d9048
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/compound_spec.rb
@@ -0,0 +1,854 @@
+module RSpec::Matchers::BuiltIn
+  RSpec.describe Compound do
+
+    let(:matcher_without_diffable) { include("foo") }
+
+    before do
+      allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)
+      allow(matcher_without_diffable).to receive(:diffable?).and_raise(NoMethodError)
+    end
+
+    shared_examples "making a copy" do |compound_method, copy_method|
+      context "when making a copy via `#{copy_method}`" do
+        it "uses a copy of the base matchers" do
+          matcher_1 = include(3)
+          matcher_2 = include(4)
+          compound  = matcher_1.__send__(compound_method, matcher_2)
+          copy = compound.__send__(copy_method)
+
+          expect(copy).not_to equal(compound)
+          expect(copy.matcher_1).not_to equal(matcher_1)
+          expect(copy.matcher_1).to be_a(RSpec::Matchers::BuiltIn::Include)
+          expect(copy.matcher_1.expected).to eq([3])
+
+          expect(copy.matcher_2).not_to equal(matcher_2)
+          expect(copy.matcher_2).to be_a(RSpec::Matchers::BuiltIn::Include)
+          expect(copy.matcher_2.expected).to eq([4])
+        end
+
+        it "copies custom matchers properly so they can work even though they have singleton behavior" do
+          matcher_1 = custom_include(3)
+          matcher_2 = custom_include(3)
+          compound  = matcher_1.__send__(compound_method, matcher_2)
+          copy = compound.__send__(copy_method)
+
+          expect(copy).not_to equal(compound)
+          expect(copy.matcher_1).not_to equal(matcher_1)
+          expect(copy.matcher_2).not_to equal(matcher_2)
+
+          expect([3]).to copy
+
+          expect { expect([4]).to copy }.to fail_matching("expected [4]")
+        end
+      end
+    end
+
+    shared_examples "handles blocks properly" do |meth|
+      define_method :combine do |m1, m2|
+        m1.__send__(meth, m2)
+      end
+
+      context "when used with a block matcher" do
+        it 'executes the block only once, regardless of how many matchers are compounded' do
+          w, x, y, z = 0, 0, 0, 0
+          expect {
+            w += 1; x += 2; y += 3; z += 4
+          }.to(                 combine(
+            change { w }.to(1), combine(
+            change { x }.to(2), combine(
+            change { y }.to(3),
+            change { z }.to(4) ) ) )
+          )
+        end
+
+        context "does not work when combined with another non-block matcher" do
+          example "with the block matcher first" do
+            expect {
+              x = 0
+              expect { x += 2 }.to combine(change { x }.to(2), be_a(Proc))
+            }.to fail_with(/supports_block_expectations/)
+          end
+
+          example "with the block matcher last" do
+            expect {
+              x = 0
+              expect { x += 2 }.to combine(be_a(Proc), change { x }.to(2))
+            }.to fail_with(/supports_block_expectations/)
+          end
+        end
+
+        context "indicates block expectations are not supported when combined with a custom matcher that does not define `supports_block_expectations?" do
+          let(:non_block_matcher) do
+            Class.new do
+              include ::RSpec::Matchers::Composable
+              def matches?(*); true; end
+            end.new
+          end
+
+          example "with the block matcher first" do
+            compound = combine(change { }.to(2), non_block_matcher)
+            expect(compound.supports_block_expectations?).to be false
+          end
+
+          example "with the block matcher last" do
+            compound = combine(non_block_matcher, change { }.to(2))
+            expect(compound.supports_block_expectations?).to be false
+          end
+        end
+
+        context "forwards on any matcher block arguments as needed (such as for `yield_with_args`)" do
+          obj = Object.new
+          def obj.foo(print_bar=true)
+            yield "bar"
+            print "printing bar" if print_bar
+          end
+
+          example "with the matcher that passes block args first" do
+            call_count = 0
+
+            expect { |probe|
+              call_count += 1
+              obj.foo(&probe)
+            }.to combine(yield_with_args(/bar/), output("printing bar").to_stdout)
+
+            expect(call_count).to eq(1)
+          end
+
+          example "with the matcher that passes block args last" do
+            call_count = 0
+
+            expect { |probe|
+              call_count += 1
+              obj.foo(&probe)
+            }.to combine(output("printing bar").to_stdout, yield_with_args("bar"))
+
+            expect(call_count).to eq(1)
+          end
+
+          it "does not support two matchers that both pass arguments to the block" do
+            expect {
+              expect { |probe|
+                obj.foo(false, &probe)
+              }.to combine(yield_with_args(/bar/), yield_with_args("bar"))
+            }.to raise_error(/cannot be combined/)
+          end
+        end
+
+        context "when used with `raise_error` (which cannot match against a wrapped block)" do
+          it 'does not work when combined with `throw_symbol` (which also cannot match against a wrapped block)' do
+            expect {
+              expect {
+              }.to combine(raise_error("boom"), throw_symbol(:foo))
+            }.to raise_error(/cannot be combined/)
+          end
+
+          it 'works when `raise_error` is first' do
+            x = 0
+            expect {
+              x += 2
+              raise "boom"
+            }.to combine(raise_error("boom"), change { x }.to(2))
+          end
+
+          it 'works when `raise_error` is last' do
+            x = 0
+            expect {
+              x += 2
+              raise "boom"
+            }.to combine(change { x }.to(2), raise_error("boom"))
+          end
+
+          context "with nested compound matchers" do
+            if meth == :or
+              def expect_block
+                @x = 0
+                expect do
+                  print "a"
+
+                  # for or we need `raise "boom"` and one other
+                  # to be wrong, so that only the `output("a").to_stdout`
+                  # is correct for these specs to cover the needed
+                  # behavior.
+                  @x += 3
+                  raise "bom"
+                end
+              end
+            else
+              def expect_block
+                @x = 0
+                expect do
+                  print "a"
+                  @x += 2
+                  raise "boom"
+                end
+              end
+            end
+
+            it 'works when `raise_error` is first in the first compound matcher' do
+              matcher = combine(
+                combine(raise_error("boom"), change { @x }.to(2)),
+                output("a").to_stdout
+              )
+
+              expect_block.to matcher
+            end
+
+            it 'works when `raise_error` is last in the first compound matcher' do
+              matcher = combine(
+                combine(change { @x }.to(2), raise_error("boom")),
+                output("a").to_stdout
+              )
+
+              expect_block.to matcher
+            end
+
+            it 'works when `raise_error` is first in the last compound matcher' do
+              matcher = combine(
+                change { @x }.to(2),
+                combine(raise_error("boom"), output("a").to_stdout)
+              )
+
+              expect_block.to matcher
+            end
+
+            it 'works when `raise_error` is last in the last compound matcher' do
+              matcher = combine(
+                change { @x }.to(2),
+                combine(output("a").to_stdout, raise_error("boom"))
+              )
+              expect_block.to matcher
+            end
+          end
+        end
+      end
+
+      context "when given a proc and non block matchers" do
+        it 'does not treat it as a block expectation expression' do
+          p = lambda { }
+          expect(p).to combine(be_a(Proc), be(p))
+
+          expect {
+            expect(p).to combine(be_a(Integer), eq(3))
+          }.to fail_matching("expected: 3")
+        end
+      end
+    end
+
+    context "when used as a composable matcher" do
+      it 'can pass' do
+        expect(["food", "barn"]).to include(
+          a_string_starting_with("f").and(ending_with("d")),
+          a_string_starting_with("b").and(ending_with("n"))
+        )
+      end
+
+      it 'can fail' do
+        expect {
+          expect(["foo", "bar"]).to include(
+            a_string_starting_with("f").and(ending_with("d")),
+            a_string_starting_with("b").and(ending_with("n"))
+          )
+        }.to fail_matching('expected ["foo", "bar"] to include (a string starting with "f" and ending with "d") and (a string starting with "b" and ending with "n")')
+      end
+
+      it 'provides a description' do
+        matcher = include(
+          a_string_starting_with("f").and(ending_with("d")),
+          a_string_starting_with("b").and(ending_with("n"))
+        )
+
+        expect(matcher.description).to eq('include (a string starting with "f" and ending with "d") and (a string starting with "b" and ending with "n")')
+      end
+    end
+
+    describe "expect(...).to matcher.and(other_matcher)" do
+
+      it_behaves_like "an RSpec matcher", :valid_value => 3, :invalid_value => 4, :disallows_negation => true do
+        let(:matcher) { eq(3).and be <= 3 }
+      end
+
+      context 'when using boolean AND `&` alias' do
+        it_behaves_like "an RSpec matcher", :valid_value => 3, :invalid_value => 4, :disallows_negation => true do
+          let(:matcher) { eq(3) & be_a(Integer) }
+        end
+      end
+
+      include_examples "making a copy", :and, :dup
+      include_examples "making a copy", :and, :clone
+      it_behaves_like  "handles blocks properly", :and
+
+      context 'when both matchers pass' do
+        it 'passes' do
+          expect(3).to eq(3).and be >= 2
+        end
+      end
+
+      it 'has a description composed of both matcher descriptions' do
+        matcher = eq(3).and be >= 2
+        expect(3).to matcher
+        expect(matcher.description).to eq("eq 3 and be >= 2")
+      end
+
+      context 'when only the first matcher fails' do
+        it "fails with the first matcher's failure message" do
+          expect {
+            expect(3).to eq(4).and be >= 2
+          }.to fail_with(dedent <<-EOS)
+            |
+            |expected: 4
+            |     got: 3
+            |
+            |(compared using ==)
+            |
+          EOS
+        end
+      end
+
+      context 'when only the second matcher fails' do
+        it "fails with the second matcher's failure message" do
+          expect {
+            expect(3).to be_kind_of(Integer).and eq(4)
+          }.to fail_with(dedent <<-EOS)
+            |
+            |expected: 4
+            |     got: 3
+            |
+            |(compared using ==)
+            |
+          EOS
+        end
+      end
+
+      context "when both mathers fail" do
+        context "when both matchers have multi-line failure messages" do
+          it 'fails with a well formatted message containing both sub-messages' do
+            expect {
+              expect(3).to eq(4).and be >= 8
+            }.to fail_with(dedent <<-EOS)
+              |
+              |   expected: 4
+              |        got: 3
+              |
+              |   (compared using ==)
+              |
+              |...and:
+              |
+              |   expected: >= 8
+              |        got:    3
+            EOS
+          end
+        end
+
+        context "when both matchers have single-line failure messages" do
+          it 'fails with a single-line failure message' do
+            expect {
+              expect("foo").to start_with("a").and end_with("z")
+            }.to fail_with('expected "foo" to start with "a" and expected "foo" to end with "z"')
+          end
+        end
+
+        context "when the first matcher has a multi-line failure message" do
+          it 'fails with a well formatted message containing both sub-messages' do
+            expect {
+              expect("foo").to eq(4).and end_with("z")
+            }.to fail_with(dedent <<-EOS)
+              |
+              |   expected: 4
+              |        got: "foo"
+              |
+              |   (compared using ==)
+              |
+              |...and:
+              |
+              |   expected "foo" to end with "z"
+            EOS
+          end
+        end
+
+        context "when the second matcher has a multi-line failure message" do
+          it 'fails with a well formatted message containing both sub-messages' do
+            expect {
+              expect("foo").to end_with("z").and eq(4)
+            }.to fail_with(dedent <<-EOS)
+              |   expected "foo" to end with "z"
+              |
+              |...and:
+              |
+              |   expected: 4
+              |        got: "foo"
+              |
+              |   (compared using ==)
+              |
+            EOS
+          end
+        end
+
+        context "when the first matcher is diffable" do
+          subject { include("foo").and be_a(String) }
+
+          it 'is diffable' do
+            expect(subject).to be_diffable
+          end
+
+          context "when only first matcher fails" do
+            it 'fails with a message containing a diff for first matcher' do
+              expected_failure = dedent(<<-EOS)
+                |Diff for (include "foo"):
+                |@@ -1,2 +1,3 @@
+                |-foo
+                |+baz
+                |+bar
+              EOS
+
+              expect {
+                expect(dedent(<<-EOS)).to subject
+                  |baz
+                  |bar
+                EOS
+              }.to fail_matching(expected_failure)
+            end
+          end
+
+          context "when only second matcher fails" do
+            subject { include("baz").and be_a(Fixnum) }
+
+            it 'fails with a message not containing a diff for first matcher' do
+              expect {
+                expect(dedent(<<-EOS)).to subject
+                  |baz
+                  |bar
+                EOS
+              }.to fail_matching(a_string_excluding "Diff")
+            end
+          end
+
+          context "when both matcher fail" do
+            subject { include("foo").and eq(35) }
+
+            it "fails with a message containing a diff with first matcher" do
+              expected_failure = dedent(<<-EOS)
+                |   expected "baz\\nbar" to include "foo"
+                |
+                |...and:
+                |
+                |   expected: 35
+                |        got: "baz\\nbar"
+                |
+                |   (compared using ==)
+                |
+                |Diff for (include "foo"):
+                |@@ -1,2 +1,3 @@
+                |-foo
+                |+baz
+                |+bar
+              EOS
+
+              expect {
+                expect(dedent(<<-EOS)).to subject
+                  |baz
+                  |bar
+                EOS
+              }.to fail_matching(expected_failure)
+            end
+          end
+        end
+
+        context "when the first matcher does not implement #diffable?" do
+          subject { matcher_without_diffable.and exist }
+
+          it 'is not diffable' do
+            expect(subject).not_to be_diffable
+          end
+        end
+
+        context "when the second matcher does not implement #diffable?" do
+          subject { exist.and matcher_without_diffable }
+
+          it 'is not diffable' do
+            expect(subject).not_to be_diffable
+          end
+        end
+
+        context "when the second matcher is diffable" do
+          subject { eq(35).and include("foo") }
+
+          it 'is diffable' do
+            expect(subject).to be_diffable
+          end
+
+          it 'fails with a message containing a diff for second matcher' do
+            expected_failure = dedent(<<-EOS)
+              |   expected: 35
+              |        got: "baz\\nbar"
+              |
+              |   (compared using ==)
+              |
+              |...and:
+              |
+              |   expected "baz\\nbar" to include "foo"
+              |Diff for (include "foo"):
+              |@@ -1,2 +1,3 @@
+              |-foo
+              |+baz
+              |+bar
+            EOS
+
+            expect {
+              expect(dedent(<<-EOS)).to subject
+                |baz
+                |bar
+              EOS
+            }.to fail_matching(expected_failure)
+          end
+        end
+
+        context "when both matchers are diffable" do
+          subject { include("bar").and include("foo") }
+
+          it 'is diffable' do
+            expect(subject).to be_diffable
+          end
+
+          it 'fails with a message containing diffs for both matcher' do
+            expected_failure = dedent(<<-EOS)
+              |expected "baz\\nbug" to include "bar" and expected "baz\\nbug" to include "foo"
+              |Diff for (include "bar"):
+              |@@ -1,2 +1,3 @@
+              |-bar
+              |+baz
+              |+bug
+              |
+              |Diff for (include "foo"):
+              |@@ -1,2 +1,3 @@
+              |-foo
+              |+baz
+              |+bug
+            EOS
+
+            expect {
+              expect(dedent(<<-EOS)).to subject
+                |baz
+                |bug
+              EOS
+            }.to fail_matching(expected_failure)
+          end
+        end
+
+        context "when both matchers are not diffable" do
+          subject { be_a(String).and be_truthy }
+
+          it 'is not diffable' do
+            expect(subject).not_to be_diffable
+          end
+
+          it 'fails with a message not containing any diff' do
+            expect {
+              expect(35).to subject
+            }.to fail_matching(a_string_excluding "Diff")
+          end
+        end
+      end
+    end
+
+    describe "expect(...).not_to matcher.and(other_matcher)" do
+      it "is not supported" do
+        expect {
+          expect(3).not_to eq(2).and be > 2
+        }.to raise_error(NotImplementedError, /matcher.and matcher` is not supported/)
+      end
+    end
+
+    describe "expect(...).to matcher.or(other_matcher)" do
+      it_behaves_like "an RSpec matcher", :valid_value => 3, :invalid_value => 5, :disallows_negation => true do
+        let(:matcher) { eq(3).or eq(4) }
+      end
+
+      context 'when using boolean OR `|` alias' do
+        it_behaves_like "an RSpec matcher", :valid_value => 3, :invalid_value => 5, :disallows_negation => true do
+          let(:matcher) { eq(3) | eq(4) }
+        end
+      end
+
+      include_examples "making a copy", :or, :dup
+      include_examples "making a copy", :or, :clone
+      it_behaves_like  "handles blocks properly", :or
+
+      it 'has a description composed of both matcher descriptions' do
+        matcher = eq(3).or eq(4)
+        expect(3).to matcher
+        expect(matcher.description).to eq("eq 3 or eq 4")
+      end
+
+      context 'when both matchers pass' do
+        it 'passes' do
+          expect("foo").to start_with("f").or end_with("o")
+        end
+      end
+
+      context 'when only the first matcher passes' do
+        it 'passes' do
+          expect("foo").to start_with("f").or end_with("z")
+        end
+      end
+
+      context 'when only the last matcher passes' do
+        it 'passes' do
+          expect("foo").to start_with("a").or end_with("o")
+        end
+      end
+
+      context 'when both matchers fail' do
+        context "when both matchers have multi-line failure messages" do
+          it 'fails with a well formatted message containing both sub-messages' do
+            expect {
+              expect(3).to eq(4).or be >= 8
+            }.to fail_with(dedent <<-EOS)
+              |
+              |   expected: 4
+              |        got: 3
+              |
+              |   (compared using ==)
+              |
+              |...or:
+              |
+              |   expected: >= 8
+              |        got:    3
+            EOS
+          end
+        end
+
+        context "when both matchers have single-line failure messages" do
+          it 'fails with a single-line failure message' do
+            expect {
+              expect("foo").to start_with("a").or end_with("z")
+            }.to fail_with('expected "foo" to start with "a" or expected "foo" to end with "z"')
+          end
+        end
+
+        context "when the first matcher has a multi-line failure message" do
+          it 'fails with a well formatted message containing both sub-messages' do
+            expect {
+              expect("foo").to eq(4).or end_with("z")
+            }.to fail_with(dedent <<-EOS)
+              |
+              |   expected: 4
+              |        got: "foo"
+              |
+              |   (compared using ==)
+              |
+              |...or:
+              |
+              |   expected "foo" to end with "z"
+            EOS
+          end
+        end
+
+        context "when the second matcher has a multi-line failure message" do
+          it 'fails with a well formatted message containing both sub-messages' do
+            expect {
+              expect("foo").to end_with("z").or eq(4)
+            }.to fail_with(dedent <<-EOS)
+              |   expected "foo" to end with "z"
+              |
+              |...or:
+              |
+              |   expected: 4
+              |        got: "foo"
+              |
+              |   (compared using ==)
+              |
+            EOS
+          end
+        end
+      end
+
+      context "when first matcher is diffable" do
+        subject { include("foo").or eq(35) }
+
+        it "is diffable" do
+          expect(subject).to be_diffable
+        end
+
+        it 'fails with a message containing diff for first matcher' do
+          expected_failure = dedent(<<-EOS)
+            |   expected "baz\\nbug" to include "foo"
+            |
+            |...or:
+            |
+            |   expected: 35
+            |        got: "baz\\nbug"
+            |
+            |   (compared using ==)
+            |
+            |Diff for (include "foo"):
+            |@@ -1,2 +1,3 @@
+            |-foo
+            |+baz
+            |+bug
+          EOS
+
+          expect {
+            expect(dedent(<<-EOS)).to subject
+              |baz
+              |bug
+            EOS
+          }.to fail_matching(expected_failure)
+        end
+      end
+
+      context "when second matcher is diffable" do
+        subject { eq(35).or include("foo") }
+
+        it "is diffable" do
+          expect(subject).to be_diffable
+        end
+
+        it 'fails with a message containing diff for second matcher' do
+          expected_failure = dedent(<<-EOS)
+            |   expected: 35
+            |        got: "baz\\nbug"
+            |
+            |   (compared using ==)
+            |
+            |...or:
+            |
+            |   expected "baz\\nbug" to include "foo"
+            |Diff for (include "foo"):
+            |@@ -1,2 +1,3 @@
+            |-foo
+            |+baz
+            |+bug
+          EOS
+
+          expect {
+            expect(dedent(<<-EOS)).to subject
+              |baz
+              |bug
+            EOS
+          }.to fail_matching(expected_failure)
+        end
+      end
+
+      context "when both matchers are diffable" do
+        subject { include("foo").or include("buzz") }
+
+        it "is diffable" do
+          expect(subject).to be_diffable
+        end
+
+        it 'fails with a message containing diffs for both matcher' do
+          expected_failure = dedent(<<-EOS)
+            |expected "baz\\nbug" to include "foo" or expected "baz\\nbug" to include "buzz"
+            |Diff for (include "foo"):
+            |@@ -1,2 +1,3 @@
+            |-foo
+            |+baz
+            |+bug
+            |
+            |Diff for (include "buzz"):
+            |@@ -1,2 +1,3 @@
+            |-buzz
+            |+baz
+            |+bug
+          EOS
+
+          expect {
+            expect(dedent(<<-EOS)).to subject
+              |baz
+              |bug
+            EOS
+          }.to fail_matching(expected_failure)
+        end
+      end
+
+      context "when both matchers are not diffable" do
+        subject { be_a(String).or be_a(Fixnum) }
+
+        it "is not diffable" do
+          expect(subject).not_to be_diffable
+        end
+
+        it 'fails with a message containing diffs for both matcher' do
+          expect {
+            expect(true).to subject
+          }.to fail_matching(a_string_excluding "Diff")
+        end
+      end
+    end
+
+    context "when chaining many matchers together" do
+      it 'can pass appropriately' do
+        matcher = start_with("f").and end_with("z").or end_with("o")
+        expect("foo").to matcher
+        expect(matcher.description).to eq('start with "f" and end with "z" or end with "o"')
+      end
+
+      it 'fails with complete diffs if its matchers are diffable' do
+        matcher = include("bar").and include("buzz").or include("foo")
+
+        expected_failure = dedent(<<-EOS)
+          |expected "bug\\nsquash" to include "bar" and expected "bug\\nsquash" to include "buzz" or expected "bug\\nsquash" to include "foo"
+          |Diff for (include "bar"):
+          |@@ -1,2 +1,3 @@
+          |-bar
+          |+bug
+          |+squash
+          |
+          |Diff for (include "buzz"):
+          |@@ -1,2 +1,3 @@
+          |-buzz
+          |+bug
+          |+squash
+          |
+          |Diff for (include "foo"):
+          |@@ -1,2 +1,3 @@
+          |-foo
+          |+bug
+          |+squash
+        EOS
+
+        expect {
+          expect(dedent(<<-EOS)).to matcher
+            |bug
+            |squash
+          EOS
+        }.to fail_matching(expected_failure)
+      end
+
+      it 'fails with a complete message' do
+        expect {
+          expect(3).to eq(1).and eq(2).and eq(3).and eq(4)
+        }.to fail_with(dedent <<-EOS)
+          |
+          |   expected: 1
+          |        got: 3
+          |
+          |   (compared using ==)
+          |
+          |...and:
+          |
+          |      expected: 2
+          |           got: 3
+          |
+          |      (compared using ==)
+          |
+          |   ...and:
+          |
+          |      expected: 4
+          |           got: 3
+          |
+          |      (compared using ==)
+          |
+        EOS
+      end
+    end
+
+    describe "expect(...).not_to matcher.or(other_matcher)" do
+      it "is not supported" do
+        expect {
+          expect(3).not_to eq(2).or be > 2
+        }.to raise_error(NotImplementedError, /matcher.or matcher` is not supported/)
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/contain_exactly_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/contain_exactly_spec.rb
new file mode 100644
index 0000000..21f5181
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/contain_exactly_spec.rb
@@ -0,0 +1,556 @@
+require 'timeout'
+
+class UnsortableObject
+  def initialize(id)
+    @id = id
+  end
+
+  def inspect
+    @id.to_s
+  end
+
+  def ==(other)
+    false
+  end
+end
+
+# AR::Relation is meant to act like a collection, but does
+# not include `Enumerable`. It does implement `to_ary`.
+class FakeActiveRecordRelation
+  def initialize(records)
+    @records = records
+  end
+
+  def to_ary
+    @records
+  end
+end
+
+RSpec.describe "should =~ array", :uses_should do
+  it "passes a valid positive expectation" do
+    [1, 2].should =~ [2, 1]
+  end
+
+  it "fails an invalid positive expectation" do
+    expect {
+      [1, 2, 3].should =~ [2, 1]
+    }.to fail_with(/expected collection contained/)
+  end
+
+  context "when the array defines a `=~` method" do
+    it 'delegates to that method rather than using the contain_exactly matcher' do
+      array = []
+      def array.=~(other)
+        other == :foo
+      end
+
+      array.should =~ :foo
+      expect {
+        array.should =~ :bar
+      }.to fail_with(/expected: :bar/)
+    end
+  end
+
+  context 'when the array defines a `send` method' do
+    it 'still works' do
+      array = [1, 2]
+      def array.send; :sent; end
+
+      array.should =~ array
+    end
+  end
+
+  context "when the array undefines `=~`" do
+    it 'still works' do
+      array_klass = Class.new(Array) { undef =~ }
+      array = array_klass.new([1, 2])
+
+      array.should =~ [1, 2]
+
+      expect {
+        array.should =~ [0, 1, 2]
+      }.to fail_with(/expected collection contained/)
+    end
+  end
+end
+
+RSpec.describe "should_not =~ [:with, :multiple, :args]", :uses_should do
+  it "fails when the arrays match" do
+    expect {
+      [1,2,3].should_not =~ [1,2,3]
+    }.to fail_with "expected [1, 2, 3] not to contain exactly 1, 2, and 3"
+  end
+
+  it "fails when the arrays match in a different order" do
+    expect {
+      [1,3,2].should_not =~ [1,2,3]
+    }.to fail_with "expected [1, 3, 2] not to contain exactly 1, 2, and 3"
+  end
+
+  it "passes when there are extra elements in the array" do
+    [1,3].should_not =~ [1,2,3]
+  end
+
+  it "passes when there are elements missing from the array" do
+    [1,2,3,4].should_not =~ [1,2,3]
+  end
+end
+
+RSpec.describe "using contain_exactly with expect" do
+  it "passes a valid positive expectation" do
+    expect([1, 2]).to contain_exactly(2, 1)
+  end
+
+  it "fails an invalid positive expectation" do
+    expect {
+      expect([1, 2, 3]).to contain_exactly(2, 1)
+    }.to fail_with(/expected collection contained/)
+  end
+
+  it "passes for an out of order valid positive expectation with hashes" do
+    expect([
+      {:a => 10},
+      {:a => -10}
+    ]).to contain_exactly(
+      {:a => (a_value < 0)},
+      {:a => (a_value > 0)}
+    )
+  end
+
+  it "passes for an in order valid positive expectation with hashes" do
+    expect([
+      {:a => 10},
+      {:a => -10}
+    ]).to contain_exactly(
+      {:a => (a_value > 0)},
+      {:a => (a_value < 0)}
+    )
+  end
+end
+
+RSpec.describe "expect(array).to contain_exactly(*other_array)" do
+  it_behaves_like "an RSpec matcher", :valid_value => [1, 2], :invalid_value => [1] do
+    let(:matcher) { contain_exactly(2, 1) }
+  end
+
+  it 'is also exposed as `match_array` (with unsplatted args)' do
+    expect([1, 2, 3]).to match_array([3, 2, 1])
+  end
+
+  it "passes if target contains all items" do
+    expect([1,2,3]).to contain_exactly(1,2,3)
+  end
+
+  it "passes if target contains all items out of order" do
+    expect([1,3,2]).to contain_exactly(1,2,3)
+  end
+
+  it 'fails if the expected array is empty and the actual array is non-empty' do
+    expect {
+      expect([1]).to contain_exactly()
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  []
+actual collection contained:    [1]
+the extra elements were:        [1]
+MESSAGE
+  end
+
+  it 'fails if the actual array is empty and the expected array is non-empty' do
+    expect {
+      expect([]).to contain_exactly(1)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1]
+actual collection contained:    []
+the missing elements were:      [1]
+MESSAGE
+  end
+
+  def timeout_if_not_debugging(time)
+    return yield if defined?(::Debugger)
+    Timeout.timeout(time) { yield }
+  end
+
+  it 'fails a match of 11 items with duplicates in a reasonable amount of time' do
+    timeout_if_not_debugging(0.1) do
+      expected = [0, 1, 1,    3, 3, 3,    4, 4,    8, 8, 9   ]
+      actual   = [   1,    2, 3, 3, 3, 3,       7, 8, 8, 9, 9]
+
+      expect {
+        expect(actual).to contain_exactly(*expected)
+      }.to fail_matching("the missing elements were:      [0, 1, 4, 4]")
+    end
+  end
+
+  it "fails if target includes extra items" do
+    expect {
+      expect([1,2,3,4]).to contain_exactly(1,2,3)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1, 2, 3]
+actual collection contained:    [1, 2, 3, 4]
+the extra elements were:        [4]
+MESSAGE
+  end
+
+  it "fails if target is missing items" do
+    expect {
+      expect([1,2]).to contain_exactly(1,2,3)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1, 2, 3]
+actual collection contained:    [1, 2]
+the missing elements were:      [3]
+MESSAGE
+  end
+
+  it "fails if target is missing items and has extra items" do
+    expect {
+      expect([1,2,4]).to contain_exactly(1,2,3)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1, 2, 3]
+actual collection contained:    [1, 2, 4]
+the missing elements were:      [3]
+the extra elements were:        [4]
+MESSAGE
+  end
+
+  it "sorts items in the error message if they all respond to <=>" do
+    expect {
+      expect([6,2,1,5]).to contain_exactly(4,1,2,3)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1, 2, 3, 4]
+actual collection contained:    [1, 2, 5, 6]
+the missing elements were:      [3, 4]
+the extra elements were:        [5, 6]
+MESSAGE
+  end
+
+    it "does not sort items in the error message if they don't all respond to <=>" do
+      expect {
+        expect([UnsortableObject.new(2), UnsortableObject.new(1)]).to contain_exactly(UnsortableObject.new(4), UnsortableObject.new(3))
+      }.to fail_with(<<-MESSAGE)
+expected collection contained:  [4, 3]
+actual collection contained:    [2, 1]
+the missing elements were:      [4, 3]
+the extra elements were:        [2, 1]
+MESSAGE
+    end
+
+  it "accurately reports extra elements when there are duplicates" do
+    expect {
+      expect([1,1,1,5]).to contain_exactly(1,5)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1, 5]
+actual collection contained:    [1, 1, 1, 5]
+the extra elements were:        [1, 1]
+MESSAGE
+  end
+
+  it "accurately reports missing elements when there are duplicates" do
+    expect {
+      expect([1,5]).to contain_exactly(1,1,5)
+    }.to fail_with(<<-MESSAGE)
+expected collection contained:  [1, 1, 5]
+actual collection contained:    [1, 5]
+the missing elements were:      [1]
+MESSAGE
+  end
+end
+
+RSpec.describe "expect(...).not_to contain_exactly(:with, :multiple, :args)" do
+  it "fails when the arrays match" do
+    expect {
+      expect([1,2,3]).not_to contain_exactly(1,2,3)
+    }.to fail_with "expected [1, 2, 3] not to contain exactly 1, 2, and 3"
+  end
+
+  it "fails when the arrays match in a different order" do
+    expect {
+      expect([1,3,2]).not_to contain_exactly(1,2,3)
+    }.to fail_with "expected [1, 3, 2] not to contain exactly 1, 2, and 3"
+  end
+
+  it "passes when there are extra elements in the array" do
+    expect([1,3]).not_to contain_exactly(1,2,3)
+  end
+
+  it "passes when there are elements missing from the array" do
+    expect([1,2,3,4]).not_to contain_exactly(1,2,3)
+  end
+end
+
+RSpec.describe "matching against things that aren't arrays" do
+  it "fails with nil and the expected error message is given" do
+    expect {
+      expect(nil).to contain_exactly(1, 2, 3)
+    }.to fail_with(/expected a collection/)
+  end
+
+  it "fails with a float and the expected error message is given" do
+    expect {
+      expect(3.7).to contain_exactly(1, 2, 3)
+    }.to fail_with(/expected a collection/)
+  end
+
+  it "fails with a string and the expected error message is given" do
+    expect {
+      expect("I like turtles").to contain_exactly(1, 2, 3)
+    }.to fail_with(/expected a collection/)
+  end
+
+  it 'works with other collection objects' do
+    expect(Set.new([3, 2, 1])).to contain_exactly(1, 2, 3)
+    expect {
+      expect(Set.new([3, 2, 1])).to contain_exactly(1, 2)
+    }.to fail_matching("expected collection contained:  [1, 2]")
+  end
+
+  it 'works with non-enumerables that implement `to_ary`' do
+    relation = FakeActiveRecordRelation.new([1, 2, 3])
+    expect(relation).to contain_exactly(2, 1, 3)
+    expect {
+      expect(relation).to contain_exactly(1, 2)
+    }.to fail_matching("expected collection contained:  [1, 2]")
+  end
+end
+
+RSpec.describe "Composing `contain_exactly` with other matchers" do
+  context "when it is compared to multiple possible matches" do
+    it 'works properly when passed as an argument in its aliased form' do
+      expect([[1, 3], ["food", "barn"]]).to include(
+        a_collection_containing_exactly(/foo/, /bar/)
+      )
+    end
+  end
+
+  describe "expect(...).to contain_exactly(matcher, matcher)" do
+    it 'passes when the array matches the matchers in the same order' do
+      expect(["food", "barn"]).to contain_exactly(
+        a_string_matching(/foo/),
+        a_string_matching(/bar/)
+      )
+    end
+
+    it 'passes when the array matches the matchers in a different order' do
+      expect(["food", "barn"]).to contain_exactly(
+        a_string_matching(/bar/),
+        a_string_matching(/foo/)
+      )
+    end
+
+    it 'fails with a useful message when there is an extra element' do
+      expect {
+        expect(["food", "barn", "goo"]).to contain_exactly(
+          a_string_matching(/bar/),
+          a_string_matching(/foo/)
+        )
+      }.to fail_with(dedent <<-EOS)
+        |expected collection contained:  [(a string matching /bar/), (a string matching /foo/)]
+        |actual collection contained:    ["barn", "food", "goo"]
+        |the extra elements were:        ["goo"]
+        |
+      EOS
+    end
+
+    it 'fails with a useful message when there is a missing element' do
+      expect {
+        expect(["food", "barn"]).to contain_exactly(
+          a_string_matching(/bar/),
+          a_string_matching(/foo/),
+          a_string_matching(/goo/)
+        )
+      }.to fail_with(dedent <<-EOS)
+        |expected collection contained:  [(a string matching /bar/), (a string matching /foo/), (a string matching /goo/)]
+        |actual collection contained:    ["barn", "food"]
+        |the missing elements were:      [(a string matching /goo/)]
+        |
+      EOS
+    end
+
+    it 'pairs up the items in order to minimize the number of unpaired items' do
+      expect {
+        expect(["fool", "food", "good"]).to contain_exactly(/foo/, /fool/, /poo/)
+      }.to fail_with(dedent <<-EOS)
+        |expected collection contained:  [/foo/, /fool/, /poo/]
+        |actual collection contained:    ["food", "fool", "good"]
+        |the missing elements were:      [/poo/]
+        |the extra elements were:        ["good"]
+        |
+      EOS
+    end
+
+    it 'provides a description' do
+      description = contain_exactly(a_string_matching(/bar/), a_string_matching(/foo/)).description
+      expect(description).to eq("contain exactly (a string matching /bar/) and (a string matching /foo/)")
+    end
+
+    context 'when an earlier matcher matches more strictly than a later matcher' do
+      it 'works when the actual items match in the same order' do
+        expect(["food", "fool"]).to contain_exactly(a_string_matching(/foo/), a_string_matching(/fool/))
+      end
+
+      it 'works when the actual items match in reverse order' do
+        expect(["fool", "food"]).to contain_exactly(a_string_matching(/foo/), a_string_matching(/fool/))
+      end
+
+      it 'can handle multiple sets of overlapping matches' do
+        expect(["fool", "barn", "bare", "food"]).to contain_exactly(
+          a_string_matching(/bar/),
+          a_string_matching(/barn/),
+          a_string_matching(/foo/),
+          a_string_matching(/fool/)
+        )
+      end
+    end
+
+    it "can use `a_value_within` and `a_string_starting_with` against multiple types of values" do
+      expect(["barn", 2.45]).to contain_exactly(
+        a_value_within(0.1).of(2.5),
+        a_string_starting_with("bar")
+      )
+    end
+
+    context 'when a later matcher matches more strictly than an earlier matcher' do
+      it 'works when the actual items match in the same order' do
+        expect(["fool", "food"]).to contain_exactly(a_string_matching(/fool/), a_string_matching(/foo/))
+      end
+
+      it 'works when the actual items match in reverse order' do
+        expect(["food", "fool"]).to contain_exactly(a_string_matching(/fool/), a_string_matching(/foo/))
+      end
+    end
+  end
+
+  describe "expect(...).to_not contain_exactly(matcher, matcher)" do
+    it 'fails when the array matches the matchers' do
+      expect {
+        expect(["food", "barn"]).to_not contain_exactly(
+          a_string_matching(/bar/),
+          a_string_matching(/foo/)
+        )
+      }.to fail_with %Q{expected ["food", "barn"] not to contain exactly }+
+                     %Q{(a string matching /bar/) and (a string matching /foo/)}
+    end
+
+    it 'passes when there is an extra element' do
+      expect(["food", "barn", "goo"]).to_not contain_exactly(
+        a_string_matching(/bar/),
+        a_string_matching(/foo/)
+      )
+    end
+
+    it 'passes when there is a missing element' do
+      expect(["food", "barn"]).to_not contain_exactly(
+        a_string_matching(/bar/),
+        a_string_matching(/foo/),
+        a_string_matching(/goo/)
+      )
+    end
+
+  end
+end
+
+module RSpec
+  module Matchers
+    module BuiltIn
+      class ContainExactly
+        RSpec.describe PairingsMaximizer do
+          it 'finds unmatched expected indexes' do
+            maximizer = PairingsMaximizer.new({ 0 => [], 1 => [0] }, { 0 => [1] })
+            expect(maximizer.solution.unmatched_expected_indexes).to eq([0])
+          end
+
+          it 'finds unmatched actual indexes' do
+            maximizer = PairingsMaximizer.new({ 0 => [0] }, { 0 => [0], 1 => [] })
+            expect(maximizer.solution.unmatched_actual_indexes).to eq([1])
+          end
+
+          describe "finding indeterminate indexes" do
+            it 'does not include unmatched indexes' do
+              maximizer = PairingsMaximizer.new({ 0 => [], 1 => [0] }, { 0 => [1], 1 => [] })
+
+              expect(maximizer.solution.indeterminate_expected_indexes).not_to include(0)
+              expect(maximizer.solution.indeterminate_actual_indexes).not_to include(1)
+            end
+
+            it 'does not include indexes that are reciprocally to exactly one index' do
+              maximizer = PairingsMaximizer.new({ 0 => [], 1 => [0] }, { 0 => [1], 1 => [0] })
+
+              expect(maximizer.solution.indeterminate_expected_indexes).not_to include(1)
+              expect(maximizer.solution.indeterminate_actual_indexes).not_to include(0)
+            end
+
+            it 'includes indexes that have multiple matches' do
+              maximizer = PairingsMaximizer.new({ 0 => [0, 2], 1 => [0, 2], 2 => [] },
+                                                { 0 => [0, 1], 1 => [], 2 => [0, 1] })
+
+
+              expect(maximizer.solution.indeterminate_expected_indexes).to include(0, 1)
+              expect(maximizer.solution.indeterminate_actual_indexes).to include(0, 2)
+            end
+
+            it 'includes indexes that have one match which has multiple matches' do
+              maximizer = PairingsMaximizer.new({ 0 => [0], 1 => [0], 2 => [1, 2] },
+                                                { 0 => [0, 1], 1 => [2], 2 => [2] })
+
+              expect(maximizer.solution.indeterminate_expected_indexes).to include(0, 1)
+              expect(maximizer.solution.indeterminate_actual_indexes).to include(1, 2)
+            end
+          end
+
+          describe "#unmatched_item_count" do
+            it 'returns the count of unmatched items' do
+              maximizer = PairingsMaximizer.new({ 0 => [1], 1 => [0] },
+                                                { 0 => [1], 1 => [0] })
+              expect(maximizer.solution.unmatched_item_count).to eq(0)
+
+              maximizer = PairingsMaximizer.new({ 0 => [1], 1 => [0] },
+                                                { 0 => [1], 1 => [0], 2 => [] })
+              expect(maximizer.solution.unmatched_item_count).to eq(1)
+            end
+          end
+
+          describe "#find_best_solution" do
+            matcher :produce_result do |unmatched_expected, unmatched_actual|
+              match do |result|
+                result.candidate? &&
+                result.unmatched_expected_indexes == unmatched_expected &&
+                result.unmatched_actual_indexes   == unmatched_actual
+              end
+
+              failure_message do |result|
+                if result.candidate_result?
+                  "expected a complete solution, but still had indeterminate indexes: " +
+                  "expected: #{result.indeterminate_expected_indexes.inspect}; " +
+                  "actual: #{result.indeterminate_actual_indexes.inspect}"
+                elsif result.unmatched_expected_indexes != unmatched_expected
+                  "expected unmatched_expected_indexes: #{unmatched_expected.inspect} " +
+                  "but got: #{result.unmatched_expected_indexes.inspect}"
+                elsif result.unmatched_actual_indexes != unmatched_actual
+                  "expected unmatched_actual_indexes: #{unmatched_actual.inspect} " +
+                  "but got: #{result.unmatched_actual_indexes.inspect}"
+                end
+              end
+            end
+
+            it 'returns no unmatched indexes when everything reciprocally matches one item' do
+              maximizer = PairingsMaximizer.new({ 0 => [1], 1 => [0] },
+                                                { 0 => [1], 1 => [0] })
+              expect(maximizer.find_best_solution).to produce_result([], [])
+            end
+
+            it 'returns unmatched indexes for everything that has no matches' do
+              maximizer = PairingsMaximizer.new({ 0 => [], 1 => [0] },
+                                                { 0 => [1], 1 => [] })
+              expect(maximizer.find_best_solution).to produce_result([0], [1])
+            end
+
+            it 'searches the solution space for a perfectly matching solution' do
+              maximizer = PairingsMaximizer.new({ 0 => [0, 1], 1 => [0] },
+                                                { 0 => [0, 1], 1 => [0] })
+              expect(maximizer.find_best_solution).to produce_result([], [])
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/cover_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/cover_spec.rb
new file mode 100644
index 0000000..4e91e93
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/cover_spec.rb
@@ -0,0 +1,67 @@
+if (1..2).respond_to?(:cover?)
+  RSpec.describe "expect(...).to cover(expected)" do
+    it_behaves_like "an RSpec matcher", :valid_value => (1..10), :invalid_value => (20..30) do
+      let(:matcher) { cover(5) }
+    end
+
+    context "for a range target" do
+      it "passes if target covers expected" do
+        expect((1..10)).to cover(5)
+      end
+
+      it "fails if target does not cover expected" do
+        expect {
+          expect((1..10)).to cover(11)
+        }.to fail_with("expected 1..10 to cover 11")
+      end
+    end
+  end
+
+  RSpec.describe "expect(...).to cover(with, multiple, args)" do
+    context "for a range target" do
+      it "passes if target covers all items" do
+        expect((1..10)).to cover(4, 6)
+      end
+
+      it "fails if target does not cover any one of the items" do
+        expect {
+          expect((1..10)).to cover(4, 6, 11)
+        }.to fail_with("expected 1..10 to cover 4, 6, and 11")
+      end
+    end
+  end
+
+  RSpec.describe "expect(...).not_to cover(expected)" do
+    context "for a range target" do
+      it "passes if target does not cover expected" do
+        expect((1..10)).not_to cover(11)
+      end
+
+      it "fails if target covers expected" do
+        expect {
+          expect((1..10)).not_to cover(5)
+        }.to fail_with("expected 1..10 not to cover 5")
+      end
+    end
+  end
+
+  RSpec.describe "expect(...).not_to cover(with, multiple, args)" do
+    context "for a range target" do
+      it "passes if the target does not cover any of the expected" do
+        expect((1..10)).not_to cover(11, 12, 13)
+      end
+
+      it "fails if the target covers all of the expected" do
+        expect {
+          expect((1..10)).not_to cover(4, 6)
+        }.to fail_with("expected 1..10 not to cover 4 and 6")
+      end
+
+      it "fails if the target covers some (but not all) of the expected" do
+        expect {
+          expect((1..10)).not_to cover(5, 11)
+        }.to fail_with("expected 1..10 not to cover 5 and 11")
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/eq_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/eq_spec.rb
new file mode 100644
index 0000000..0e0e933
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/eq_spec.rb
@@ -0,0 +1,176 @@
+require 'date'
+# complex is available w/o requiring on ruby 1.9+.
+# Loading it on 1.9+ issues a warning, so we only load it on 1.8.7.
+require 'complex' if RUBY_VERSION == '1.8.7'
+require 'bigdecimal'
+
+module RSpec
+  module Matchers
+    RSpec.describe "eq" do
+      it_behaves_like "an RSpec matcher", :valid_value => 1, :invalid_value => 2 do
+        let(:matcher) { eq(1) }
+      end
+
+      it "is diffable" do
+        expect(eq(1)).to be_diffable
+      end
+
+      it "matches when actual == expected" do
+        expect(1).to eq(1)
+      end
+
+      it "does not match when actual != expected" do
+        expect(1).not_to eq(2)
+      end
+
+      it "compares by sending == to actual (not expected)" do
+        called = false
+        actual = Class.new do
+          define_method :== do |other|
+            called = true
+          end
+        end.new
+
+        expect(actual).to eq :anything # to trigger the matches? method
+        expect(called).to be_truthy
+      end
+
+      it "describes itself" do
+        matcher = eq(1)
+        matcher.matches?(1)
+        expect(matcher.description).to eq "eq 1"
+      end
+
+      it "provides message, expected and actual on #failure_message" do
+        matcher = eq("1")
+        matcher.matches?(1)
+        expect(matcher.failure_message).to eq "\nexpected: \"1\"\n     got: 1\n\n(compared using ==)\n"
+      end
+
+      it "provides message, expected and actual on #negative_failure_message" do
+        matcher = eq(1)
+        matcher.matches?(1)
+        expect(matcher.failure_message_when_negated).to eq "\nexpected: value != 1\n     got: 1\n\n(compared using ==)\n"
+      end
+
+      it 'fails properly when the actual is an array of multiline strings' do
+        expect {
+          expect(["a\nb", "c\nd"]).to eq([])
+        }.to fail_matching("expected: []")
+      end
+
+      describe '#description' do
+        [
+            [nil, 'eq nil'],
+            [true, 'eq true'],
+            [false, 'eq false'],
+            [:symbol, 'eq :symbol'],
+            [1, 'eq 1'],
+            [1.2, 'eq 1.2'],
+            [Complex(1, 2), "eq #{Complex(1, 2).inspect}"],
+            ['foo', 'eq "foo"'],
+            [/regex/, 'eq /regex/'],
+            [['foo'], 'eq ["foo"]'],
+            [{:foo => :bar}, 'eq {:foo=>:bar}'],
+            [Class, 'eq Class'],
+            [RSpec, 'eq RSpec'],
+            [Date.new(2014, 1, 1), "eq #{Date.new(2014, 1, 1).inspect}"],
+            [Time.utc(2014, 1, 1), "eq #{Time.utc(2014, 1, 1).inspect}"],
+        ].each do |expected, expected_description|
+          context "with #{expected.inspect}" do
+            it "is \"#{expected_description}\"" do
+              expect(eq(expected).description).to eq expected_description
+            end
+          end
+        end
+
+        context 'with object' do
+          it 'matches with "^eq #<Object:0x[0-9a-f]*>$"' do
+            expect(eq(Object.new).description).to match(/^eq #<Object:0x[0-9a-f]*>$/)
+          end
+        end
+      end
+
+      context "Time Equality" do
+        RSpec::Matchers.define :a_string_with_differing_output do
+          match do |string|
+            time_strings = /expected: (.+)\n.*got: (.+)$/.match(string).captures
+            time_strings.uniq.count == 2
+          end
+        end
+
+        RSpec::Matchers.define :a_string_with_identical_output do
+          match do |string|
+            time_strings = /expected: value != (.+)\n.*got: (.+)$/.match(string).captures
+            time_strings.uniq.count == 1
+          end
+        end
+
+        context 'with Time objects' do
+          let(:time1) { Time.utc(1969, 12, 31, 19, 01, 40, 101) }
+          let(:time2) { Time.utc(1969, 12, 31, 19, 01, 40, 102) }
+
+          it 'produces different output for Times differing by milliseconds' do
+            expect {
+              expect(time1).to eq(time2)
+            }.to fail_with(a_string_with_differing_output)
+          end
+        end
+
+        context 'with DateTime objects' do
+          let(:date1) { DateTime.new(2000, 1, 1, 1, 1, Rational(1, 10)) }
+          let(:date2) { DateTime.new(2000, 1, 1, 1, 1, Rational(2, 10)) }
+
+          it 'produces different output for DateTimes differing by milliseconds' do
+            expect {
+              expect(date1).to eq(date2)
+            }.to fail_with(a_string_with_differing_output)
+          end
+
+          it 'does not not assume DateTime is defined since you need to require `date` to make it available' do
+            hide_const('DateTime')
+            expect {
+              expect(5).to eq(4)
+            }.to raise_error(RSpec::Expectations::ExpectationNotMetError)
+          end
+
+          it 'fails with identical output when the DateTimes are exactly the same' do
+            expect {
+              expect(date1).to_not eq(date1)
+            }.to fail_with(a_string_with_identical_output)
+          end
+
+          context 'when ActiveSupport is loaded' do
+            it "uses a custom format to ensure the output is different when DateTimes differ" do
+              stub_const("ActiveSupport", Module.new)
+              allow(date1).to receive(:inspect).and_return("Timestamp")
+              allow(date2).to receive(:inspect).and_return("Timestamp")
+
+              expect {
+                expect(date1).to eq(date2)
+              }.to fail_with(a_string_with_differing_output)
+            end
+          end
+        end
+      end
+
+      context 'with BigDecimal objects' do
+        let(:float)   { 1.1 }
+        let(:decimal) { BigDecimal("3.3") }
+
+        it 'fails with a conventional representation of the decimal' do
+          expect {
+            expect(float).to eq(decimal)
+          }.to fail_matching "expected: 3.3 (#<BigDecimal"
+        end
+
+        it 'does not not assume BigDecimal is defined since you need to require `bigdecimal` to make it available' do
+          hide_const('BigDecimal')
+          expect {
+            expect(5).to eq(4)
+          }.to raise_error(RSpec::Expectations::ExpectationNotMetError)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/eql_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/eql_spec.rb
new file mode 100644
index 0000000..4491fc9
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/eql_spec.rb
@@ -0,0 +1,39 @@
+module RSpec
+  module Matchers
+    RSpec.describe "eql" do
+      it_behaves_like "an RSpec matcher", :valid_value => 1, :invalid_value => 2 do
+        let(:matcher) { eql(1) }
+      end
+
+      it "is diffable" do
+        expect(eql(1)).to be_diffable
+      end
+
+      it "matches when actual.eql?(expected)" do
+        expect(1).to eql(1)
+      end
+
+      it "does not match when !actual.eql?(expected)" do
+        expect(1).not_to eql(2)
+      end
+
+      it "describes itself" do
+        matcher = eql(1)
+        matcher.matches?(1)
+        expect(matcher.description).to eq "eql 1"
+      end
+
+      it "provides message, expected and actual on #failure_message" do
+        matcher = eql("1")
+        matcher.matches?(1)
+        expect(matcher.failure_message).to eq "\nexpected: \"1\"\n     got: 1\n\n(compared using eql?)\n"
+      end
+
+      it "provides message, expected and actual on #negative_failure_message" do
+        matcher = eql(1)
+        matcher.matches?(1)
+        expect(matcher.failure_message_when_negated).to eq "\nexpected: value != 1\n     got: 1\n\n(compared using eql?)\n"
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/equal_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/equal_spec.rb
new file mode 100644
index 0000000..a9c84d4
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/equal_spec.rb
@@ -0,0 +1,130 @@
+module RSpec
+  module Matchers
+    RSpec.describe "equal" do
+      it_behaves_like "an RSpec matcher", :valid_value => :a, :invalid_value => :b do
+        let(:matcher) { equal(:a) }
+      end
+
+      def inspect_object(o)
+        "#<#{o.class}:#{o.object_id}> => #{o.inspect}"
+      end
+
+      it "matches when actual.equal?(expected)" do
+        expect(1).to equal(1)
+      end
+
+      it "does not match when !actual.equal?(expected)" do
+        expect("1").not_to equal("1")
+      end
+
+      it "describes itself" do
+        matcher = equal(1)
+        matcher.matches?(1)
+        expect(matcher.description).to eq "equal 1"
+      end
+
+      context "when the expected object is falsey in conditinal semantics" do
+        it "describes itself with the expected object" do
+          matcher = equal(nil)
+          matcher.matches?(nil)
+          expect(matcher.description).to eq "equal nil"
+        end
+      end
+
+      context "when the expected object's #equal? always returns true" do
+        let(:strange_string) do
+          string = "foo"
+
+          def string.equal?(other)
+            true
+          end
+
+          string
+        end
+
+        it "describes itself with the expected object" do
+          matcher = equal(strange_string)
+          matcher.matches?(strange_string)
+          expect(matcher.description).to eq 'equal "foo"'
+        end
+      end
+
+      context "the output for expected" do
+        it "doesn't include extra object detail for `true`" do
+          expected, actual = true, "1"
+          expect {
+            expect(actual).to equal(expected)
+          }.to fail_with "\nexpected true\n     got #{inspect_object(actual)}\n"
+        end
+
+        it "doesn't include extra object detail for `false`" do
+          expected, actual = false, "1"
+          expect {
+            expect(actual).to equal(expected)
+          }.to fail_with "\nexpected false\n     got #{inspect_object(actual)}\n"
+        end
+
+        it "doesn't include extra object detail for `nil`" do
+          expected, actual = nil, "1"
+          expect {
+            expect(actual).to equal(expected)
+          }.to fail_with "\nexpected nil\n     got #{inspect_object(actual)}\n"
+        end
+      end
+
+      context "the output for actual" do
+        it "doesn't include extra object detail for `true`" do
+          expected, actual = true, false
+          expect {
+            expect(actual).to equal(expected)
+          }.to fail_with "\nexpected true\n     got false\n"
+        end
+
+        it "doesn't include extra object detail for `false`" do
+          expected, actual = false, nil
+          expect {
+            expect(actual).to equal(expected)
+          }.to fail_with "\nexpected false\n     got nil\n"
+        end
+
+        it "doesn't include extra object detail for `nil`" do
+          expected, actual = nil, false
+          expect {
+            expect(actual).to equal(expected)
+          }.to fail_with "\nexpected nil\n     got false\n"
+        end
+      end
+
+      it "suggests the `eq` matcher on failure" do
+        expected, actual = "1", "1"
+        expect {
+          expect(actual).to equal(expected)
+        }.to fail_with <<-MESSAGE
+
+expected #{inspect_object(expected)}
+     got #{inspect_object(actual)}
+
+Compared using equal?, which compares object identity,
+but expected and actual are not the same object. Use
+`expect(actual).to eq(expected)` if you don't care about
+object identity in this example.
+
+MESSAGE
+      end
+
+      it "provides message on #negative_failure_message" do
+        expected = actual = "1"
+        matcher = equal(expected)
+        matcher.matches?(actual)
+        expect(matcher.failure_message_when_negated).to eq <<-MESSAGE
+
+expected not #{inspect_object(expected)}
+         got #{inspect_object(actual)}
+
+Compared using equal?, which compares object identity.
+
+MESSAGE
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/exist_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/exist_spec.rb
new file mode 100644
index 0000000..afe0348
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/exist_spec.rb
@@ -0,0 +1,139 @@
+require 'ostruct'
+
+RSpec.describe "exist matcher" do
+  it_behaves_like "an RSpec matcher", :valid_value => OpenStruct.new(:exist? => true),
+                                      :invalid_value => OpenStruct.new(:exist? => false) do
+    let(:matcher) { exist }
+  end
+
+  context "when the object does not respond to #exist? or #exists?" do
+    subject { double }
+
+    [:to, :not_to].each do |expect_method|
+      describe "expect(...).#{expect_method} exist" do
+        it "fails" do
+          expect {
+            expect(subject).send(expect_method, exist)
+          }.to fail_matching("it does not respond to either `exist?` or `exists?`")
+        end
+      end
+    end
+  end
+
+  it 'composes gracefully' do
+    expect([
+      double,
+      double(:exists? => false),
+      double(:exists? => true),
+    ]).to include existing
+  end
+
+  [:exist?, :exists?].each do |predicate|
+    context "when the object responds to ##{predicate}" do
+      describe "expect(...).to exist" do
+        it "passes if #{predicate}" do
+          expect(double(predicate => true)).to exist
+        end
+
+        it "fails if not #{predicate}" do
+          expect {
+            expect(double(predicate => false)).to exist
+          }.to fail_with(/expected .* to exist/)
+        end
+
+        it 'works when the object overrides `send`' do
+          klass = Struct.new(:message) do
+            def send
+              :message_sent
+            end
+
+            define_method predicate do
+              true
+            end
+          end
+
+          expect(klass.new("msg")).to exist
+        end
+      end
+
+      describe "expect(...).not_to exist" do
+        it "passes if not #{predicate}" do
+          expect(double(predicate => false)).not_to exist
+        end
+
+        it "fails if #{predicate}" do
+          expect {
+            expect(double(predicate => true)).not_to exist
+          }.to fail_with(/expected .* not to exist/)
+        end
+      end
+    end
+  end
+
+  context "when the object responds to #exist? and #exists?" do
+    context "when they both return falsey values" do
+      subject { double(:exist? => false, :exists? => nil) }
+
+      describe "expect(...).not_to exist" do
+        it "passes" do
+          expect(subject).not_to exist
+        end
+      end
+
+      describe "expect(...).to exist" do
+        it "fails" do
+          expect {
+            expect(subject).to exist
+          }.to fail_with(/expected .* to exist/)
+        end
+      end
+    end
+
+    context "when they both return truthy values" do
+      subject { double(:exist? => true, :exists? => "something true") }
+
+      describe "expect(...).not_to exist" do
+        it "fails" do
+          expect {
+            expect(subject).not_to exist
+          }.to fail_with(/expected .* not to exist/)
+        end
+      end
+
+      describe "expect(...).to exist" do
+        it "passes" do
+          expect(subject).to exist
+        end
+      end
+    end
+
+    context "when they return values with different truthiness" do
+      subject { double(:exist? => true, :exists? => false) }
+
+      [:to, :not_to].each do |expect_method|
+        describe "expect(...).#{expect_method} exist" do
+          it "fails" do
+            expect {
+              expect(subject).send(expect_method, exist)
+            }.to fail_matching("`exist?` and `exists?` returned different values")
+          end
+        end
+      end
+    end
+  end
+
+  it 'passes any provided arguments to the call to #exist?' do
+    object = double
+    expect(object).to receive(:exist?).with(:foo, :bar) { true }.at_least(:once)
+
+    expect(object).to exist(:foo, :bar)
+  end
+
+  it 'memoizes the call to `exist?` because it can be expensive (such as doing a DB query)' do
+    object = double
+    allow(object).to receive(:exist?) { false }
+    expect { expect(object).to exist }.to fail
+
+    expect(object).to have_received(:exist?).once
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/has_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/has_spec.rb
new file mode 100644
index 0000000..8e1a29f
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/has_spec.rb
@@ -0,0 +1,179 @@
+RSpec.describe "expect(...).to have_sym(*args)" do
+  it_behaves_like "an RSpec matcher", :valid_value => { :a => 1 },
+                                      :invalid_value => {} do
+    let(:matcher) { have_key(:a) }
+  end
+
+  it "passes if #has_sym?(*args) returns true" do
+    expect({:a => "A"}).to have_key(:a)
+  end
+
+  it "fails if #has_sym?(*args) returns false" do
+    expect {
+      expect({:b => "B"}).to have_key(:a)
+    }.to fail_with("expected #has_key?(:a) to return true, got false")
+  end
+
+  obj_with_block_method = Object.new
+  def obj_with_block_method.has_some_stuff?; yield; end
+
+  it 'forwards the given `{ }` block on to the `has_xyz?` method' do
+    expect(obj_with_block_method).to have_some_stuff { true }
+    expect(obj_with_block_method).to_not have_some_stuff { false }
+  end
+
+  it 'forwards the given `do..end` block on to the `has_xyz?` method' do
+    expect(obj_with_block_method).to have_some_stuff do
+      true
+    end
+
+    expect(obj_with_block_method).to_not have_some_stuff do
+      false
+    end
+  end
+
+  it 'favors a curly brace block over a do...end one since it binds to the matcher method' do
+    expect(obj_with_block_method).to have_some_stuff { true } do
+      false
+    end
+
+    expect(obj_with_block_method).not_to have_some_stuff { false } do
+      true
+    end
+  end
+
+  it 'does not include any args in the failure message if no args were given to the matcher' do
+    o = Object.new
+    def o.has_some_stuff?; false; end
+    expect {
+      expect(o).to have_some_stuff
+    }.to fail_with("expected #has_some_stuff? to return true, got false")
+  end
+
+  it 'includes multiple args in the failure message if multiple args were given to the matcher' do
+    o = Object.new
+    def o.has_some_stuff?(*_); false; end
+    expect {
+      expect(o).to have_some_stuff(:a, 7, "foo")
+    }.to fail_with('expected #has_some_stuff?(:a, 7, "foo") to return true, got false')
+  end
+
+  it "fails if #has_sym?(*args) returns nil" do
+    klass = Class.new do
+      def has_foo?
+      end
+    end
+    expect {
+      expect(klass.new).to have_foo
+    }.to fail_with(/expected #has_foo.* to return true, got false/)
+  end
+
+  it 'fails if #has_sym?(*args) is private' do
+    klass = Class.new do
+      private
+      def has_foo?
+        true
+      end
+    end
+    expect { expect(klass.new).to have_foo }.to fail_with(/private/)
+  end
+
+  it "fails if target does not respond to #has_sym?" do
+    expect {
+      expect(Object.new).to have_key(:a)
+    }.to fail_matching('to respond to `has_key?`')
+  end
+
+  it "reraises an exception thrown in #has_sym?(*args)" do
+    o = Object.new
+    def o.has_sym?(*args)
+      raise "Funky exception"
+    end
+    expect {
+      expect(o).to have_sym(:foo)
+    }.to raise_error("Funky exception")
+  end
+
+  it 'allows composable aliases to be defined' do
+    RSpec::Matchers.alias_matcher :an_object_having_sym, :have_sym
+    o = Object.new
+    def o.has_sym?(sym); sym == :foo; end
+
+    expect(o).to an_object_having_sym(:foo)
+    expect(o).not_to an_object_having_sym(:bar)
+
+    expect(an_object_having_sym(:foo).description).to eq("an object having sym :foo")
+  end
+
+  it 'composes gracefully' do
+    RSpec::Matchers.alias_matcher :an_object_having_foo, :have_foo
+
+    expect([
+      double,
+      double(:has_foo? => false),
+      double(:has_foo? => true),
+    ]).to include an_object_having_foo
+  end
+end
+
+RSpec.describe "expect(...).not_to have_sym(*args)" do
+  it "passes if #has_sym?(*args) returns false" do
+    expect({:a => "A"}).not_to have_key(:b)
+  end
+
+  it "passes if #has_sym?(*args) returns nil" do
+    klass = Class.new do
+      def has_foo?
+      end
+    end
+    expect(klass.new).not_to have_foo
+  end
+
+  it "fails if #has_sym?(*args) returns true" do
+    expect {
+      expect({:a => "A"}).not_to have_key(:a)
+    }.to fail_with("expected #has_key?(:a) to return false, got true")
+  end
+
+  it "fails if target does not respond to #has_sym?" do
+    expect {
+      expect(Object.new).not_to have_key(:a)
+    }.to fail_matching('to respond to `has_key?`')
+  end
+
+  it "reraises an exception thrown in #has_sym?(*args)" do
+    o = Object.new
+    def o.has_sym?(*args)
+      raise "Funky exception"
+    end
+    expect {
+      expect(o).not_to have_sym(:foo)
+    }.to raise_error("Funky exception")
+  end
+
+  it 'does not include any args in the failure message if no args were given to the matcher' do
+    o = Object.new
+    def o.has_some_stuff?; true; end
+    expect {
+      expect(o).not_to have_some_stuff
+    }.to fail_with("expected #has_some_stuff? to return false, got true")
+  end
+
+  it 'includes multiple args in the failure message if multiple args were given to the matcher' do
+    o = Object.new
+    def o.has_some_stuff?(*_); true; end
+    expect {
+      expect(o).not_to have_some_stuff(:a, 7, "foo")
+    }.to fail_with('expected #has_some_stuff?(:a, 7, "foo") to return false, got true')
+  end
+end
+
+RSpec.describe "has" do
+  it "works when the target implements #send" do
+    o = {:a => "A"}
+    def o.send(*args); raise "DOH! Library developers shouldn't use #send!" end
+    expect {
+      expect(o).to have_key(:a)
+    }.not_to raise_error
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/have_attributes_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/have_attributes_spec.rb
new file mode 100644
index 0000000..2d22051
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/have_attributes_spec.rb
@@ -0,0 +1,230 @@
+RSpec.describe "#have_attributes matcher" do
+
+  Person = Struct.new(:name, :age)
+
+  class Person
+    def parent(parent_name)
+      @parent = parent_name
+    end
+  end
+
+  let(:wrong_name) { "Wrong Name" }
+  let(:wrong_age) { 11 }
+
+  let(:correct_name) { "Correct name" }
+  let(:correct_age) { 33 }
+
+  let(:person) { Person.new(correct_name, correct_age) }
+
+  it "is diffable" do
+    expect(have_attributes(:age => correct_age)).to be_diffable
+  end
+
+  describe "expect(...).to have_attributes(with_one_attribute)" do
+
+    it_behaves_like "an RSpec matcher", :valid_value => Person.new("Correct name", 33), :invalid_value => Person.new("Wrong Name", 11) do
+      let(:matcher) { have_attributes(:name => "Correct name") }
+    end
+
+    it "passes if target has the provided attributes" do
+      expect(person).to have_attributes(:name => correct_name)
+    end
+
+    it "fails if target does not have any of the expected attributes" do
+      expect {
+        expect(person).to have_attributes(:name => wrong_name)
+      }.to fail_matching(%r|expected #{object_inspect person} to have attributes #{hash_inspect :name => wrong_name} but had attributes #{hash_inspect :name => correct_name }|)
+    end
+
+    it "fails with correct message if object manipulates its data" do
+      counter = Class.new do
+        def initialize; @count = 1; end
+        def count
+          @count += 1
+        end
+      end.new
+      expect {
+        expect(counter).to have_attributes(:count => 1)
+      }.to fail_matching(%r|to have attributes #{hash_inspect :count => 1} but had attributes #{hash_inspect :count => 2 }|)
+    end
+
+    it 'diffs the attributes received with those expected' do
+      allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)
+
+      expected_diff = dedent(<<-EOS)
+        |@@ -1,2 +1,2 @@
+        |-:name => "Wrong Name",
+        |+:name => "Correct name",
+      EOS
+
+      expect {
+        expect(person).to have_attributes(:name => wrong_name)
+      }.to fail_matching(expected_diff)
+    end
+
+    it "fails if target does not responds to any of the attributes" do
+      expect {
+        expect(person).to have_attributes(:color => 'red')
+      }.to fail_matching("expected #{object_inspect person} to respond to :color")
+    end
+
+    it "doesn't produce a diff if the target fails the respond to check" do
+      expect {
+        expect(person).to have_attributes(:color => 'red')
+      }.to fail_with(a_string_excluding "Diff")
+    end
+
+    it "fails if target responds to the attribute but requires arguments" do
+      expect {
+        expect(person).to have_attributes(:parent => 'Billy')
+      }.to fail_matching("expected #{object_inspect person} to respond to :parent with 0 arguments")
+    end
+
+    describe "expect(...).to have_attributes(key => matcher)" do
+
+      it "passes when the matchers match" do
+        expect(person).to have_attributes(:age => (a_value > 30))
+      end
+
+      it 'provides a description' do
+        description = have_attributes(:age => (a_value > 30)).description
+        expect(description).to eq("have attributes {:age => (a value > 30)}")
+      end
+
+      it "fails with a clear message when the matcher does not match" do
+        expect {
+          expect(person).to have_attributes(:age => (a_value < 10))
+        }.to fail_matching("expected #{object_inspect person} to have attributes {:age => (a value < 10)}")
+      end
+    end
+  end
+
+  describe "expect(...).to_not have_attributes(with_one_attribute)" do
+
+    it "passes if target does not have any of the expected attributes" do
+      expect(person).to_not have_attributes(:age => wrong_age)
+    end
+
+    it "fails if target has all of the expected attributes" do
+      expect {
+        expect(person).to_not have_attributes(:age => correct_age)
+      }.to fail_matching(%r|expected #{object_inspect person} not to have attributes #{hash_inspect :age => correct_age}|)
+    end
+
+    it "doesn't produce a diff" do
+      expect {
+        expect(person).to_not have_attributes(:age => correct_age)
+      }.to fail_with(a_string_excluding "Diff")
+    end
+
+    it "fails if target does not responds to any of the attributes" do
+      expect {
+        expect(person).to_not have_attributes(:color => 'red')
+      }.to fail_matching("expected #{object_inspect person} to respond to :color")
+    end
+
+    it "fails if target responds to the attribute but requires arguments" do
+      expect {
+        expect(person).to_not have_attributes(:parent => 'Billy')
+      }.to fail_matching("expected #{object_inspect person} to respond to :parent with 0 arguments")
+    end
+  end
+
+  describe "expect(...).to have_attributes(with_multiple_attributes)" do
+
+    it_behaves_like "an RSpec matcher", :valid_value => Person.new("Correct name", 33), :invalid_value => Person.new("Wrong Name", 11) do
+      let(:matcher) { have_attributes(:name => "Correct name", :age => 33) }
+    end
+
+    it "passes if target has the provided attributes" do
+      expect(person).to have_attributes(:name => correct_name, :age => correct_age)
+    end
+
+    it "fails if target does not have any of the expected attributes" do
+      expect {
+        expect(person).to have_attributes(:name => correct_name, :age => wrong_age)
+      }.to fail_matching(%r|expected #{object_inspect person} to have attributes #{hash_inspect :name => correct_name, :age => wrong_age}|)
+    end
+
+    it 'diffs the attributes received with those expected' do
+      allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)
+
+      expected_diff = dedent(<<-EOS)
+        |@@ -1,3 +1,3 @@
+        |-:age => 11,
+        |+:age => 33,
+        | :name => "Correct name",
+      EOS
+
+      expect {
+        expect(person).to have_attributes(:name => correct_name, :age => wrong_age)
+      }.to fail_matching(expected_diff)
+    end
+
+    it "fails if target does not responds to any of the attributes" do
+      expect {
+        expect(person).to have_attributes(:name => correct_name, :color => 'red')
+      }.to fail_matching("expected #{object_inspect person} to respond to :color")
+    end
+
+    it "fails if target responds to the attribute but requires arguments" do
+      expect {
+        expect(person).to have_attributes(:name => correct_name, :parent => 'Billy')
+      }.to fail_matching("expected #{object_inspect person} to respond to :parent with 0 arguments")
+    end
+  end
+
+  describe "expect(...).to_not have_attributes(with_multiple_attributes)" do
+
+    it "passes if target has none of the expected attributes" do
+      expect(person).to_not have_attributes(:name => wrong_name, :age => wrong_age)
+    end
+
+    it "fails if target has any of the expected attributes" do
+      expect {
+        expect(person).to_not have_attributes(:name => wrong_name, :age => correct_age)
+      }.to fail_matching(%r|expected #{object_inspect person} not to have attributes #{hash_inspect :name => wrong_name, :age => correct_age}|)
+    end
+
+    it "fails if target has all of the expected attributes" do
+      expect {
+        expect(person).to_not have_attributes(:name => correct_name, :age => correct_age)
+      }.to fail_matching(%r|expected #{object_inspect person} not to have attributes #{hash_inspect :name => correct_name, :age => correct_age}|)
+    end
+
+    it "fails if target does not responds to any of the attributes" do
+      expect {
+        expect(person).to_not have_attributes(:name => correct_name, :color => 'red')
+      }.to fail_matching("expected #{object_inspect person} to respond to :color")
+    end
+
+    it "fails if target responds to the attribute but requires arguments" do
+      expect {
+        expect(person).to_not have_attributes(:name => correct_name, :parent => 'Billy')
+      }.to fail_matching("expected #{object_inspect person} to respond to :parent with 0 arguments")
+    end
+  end
+
+
+  include RSpec::Matchers::Pretty
+  # We have to use Hash#inspect in examples that have multi-entry
+  # hashes because the #inspect output on 1.8.7 is non-deterministic
+  # due to the fact that hashes are not ordered. So we can't simply
+  # put a literal string for what we expect because it varies.
+  if RUBY_VERSION.to_f == 1.8
+    def hash_inspect(hash)
+      /\{(#{hash.map { |key,value| "#{key.inspect} => #{value.inspect}.*" }.join "|" }){#{hash.size}}\}/
+    end
+  else
+    def hash_inspect(hash)
+      improve_hash_formatting hash.inspect
+    end
+  end
+
+  include RSpec::Matchers::Composable
+  # a helper for failure message assertion
+  def object_inspect(object)
+    surface_descriptions_in object.inspect
+  end
+
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/include_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/include_spec.rb
new file mode 100644
index 0000000..9bbd235
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/include_spec.rb
@@ -0,0 +1,587 @@
+require 'uri'
+
+RSpec.describe "#include matcher" do
+  it "is diffable" do
+    expect(include("a")).to be_diffable
+  end
+
+  describe "expect(...).to include(with_one_arg)" do
+    it_behaves_like "an RSpec matcher", :valid_value => [1, 2], :invalid_value => [1] do
+      let(:matcher) { include(2) }
+    end
+
+    context "for an object that does not respond to `include?`" do
+      it 'fails gracefully' do
+        expect {
+          expect(5).to include(1)
+        }.to fail_matching("expected 5 to include 1, but it does not respond to `include?`")
+      end
+    end
+
+    context "for an arbitrary object that responds to `include?`" do
+      it 'delegates to `include?`' do
+        container = double("Container")
+        allow(container).to receive(:include?) { |arg| arg == :stuff }
+
+        expect(container).to include(:stuff)
+
+        expect {
+          expect(container).to include(:space)
+        }.to fail_matching("to include :space")
+      end
+    end
+
+    context "for a string target" do
+      it "passes if target includes expected" do
+        expect("abc").to include("a")
+      end
+
+      it "fails if target does not include expected" do
+        expect {
+          expect("abc").to include("d")
+        }.to fail_matching("expected \"abc\" to include \"d\"")
+      end
+
+      it "includes a diff when actual is multiline" do
+        expect {
+          expect("abc\ndef").to include("g")
+        }.to fail_matching("expected \"abc\\ndef\" to include \"g\"\nDiff")
+      end
+
+      it "includes a diff when actual is multiline and there are multiple expecteds" do
+        expect {
+          expect("abc\ndef").to include("g", "h")
+        }.to fail_matching("expected \"abc\\ndef\" to include \"g\" and \"h\"\nDiff")
+      end
+    end
+
+    context "for an array target" do
+      it "passes if target includes expected" do
+        expect([1,2,3]).to include(3)
+      end
+
+      it "fails if target does not include expected" do
+        expect {
+          expect([1,2,3]).to include(4)
+        }.to fail_matching("expected [1, 2, 3] to include 4")
+      end
+
+      it 'fails when given differing null doubles' do
+        dbl_1 = double.as_null_object
+        dbl_2 = double.as_null_object
+
+        expect {
+          expect([dbl_1]).to include(dbl_2)
+        }.to fail_matching("expected [#{dbl_1.inspect}] to include")
+      end
+
+      it 'passes when given the same null double' do
+        dbl = double.as_null_object
+        expect([dbl]).to include(dbl)
+      end
+    end
+
+    context "for a hash target" do
+      it 'passes if target has the expected as a key' do
+        expect({:key => 'value'}).to include(:key)
+      end
+
+      it "fails if target does not include expected" do
+        expect {
+          expect({:key => 'value'}).to include(:other)
+        }.to fail_matching(%Q|expected {:key => "value"} to include :other|)
+      end
+
+      it "fails if target doesn't have a key and we expect nil" do
+        expect {
+          expect({}).to include(:something => nil)
+        }.to fail_matching(%Q|expected {} to include {:something => nil}|)
+      end
+
+      it 'works even when an entry in the hash overrides #send' do
+        hash = { :key => 'value' }
+        def hash.send; :sent; end
+        expect(hash).to include(hash)
+      end
+
+      context 'that overrides #send' do
+        it 'still works' do
+          array = [1, 2]
+          def array.send; :sent; end
+
+          expect(array).to include(*array)
+        end
+      end
+    end
+  end
+
+  describe "expect(...).to include(with, multiple, args)" do
+    it "has a description" do
+      matcher = include("a")
+      expect(matcher.description).to eq("include \"a\"")
+    end
+    context "for a string target" do
+      it "passes if target includes all items" do
+        expect("a string").to include("str", "a")
+      end
+
+      it "fails if target does not include any one of the items" do
+        expect {
+          expect("a string").to include("str", "a", "foo")
+        }.to fail_matching(%Q{expected "a string" to include "str", "a", and "foo"})
+      end
+    end
+
+    context "for an array target" do
+      it "passes if target includes all items" do
+        expect([1,2,3]).to include(1,2,3)
+      end
+
+      it "fails if target does not include any one of the items" do
+        expect {
+          expect([1,2,3]).to include(1,2,4)
+        }.to fail_matching("expected [1, 2, 3] to include 1, 2, and 4")
+      end
+    end
+
+    context "for a hash target" do
+      it 'passes if target includes all items as keys' do
+        expect({:key => 'value', :other => 'value'}).to include(:key, :other)
+      end
+
+      it 'fails if target is missing any item as a key' do
+        expect {
+          expect({:key => 'value'}).to include(:key, :other)
+        }.to fail_matching(%Q|expected {:key => "value"} to include :key and :other|)
+      end
+    end
+  end
+
+  describe "expect(...).not_to include(expected)" do
+    context "for an object that does not respond to `include?`" do
+      it 'fails gracefully' do
+        expect {
+          expect(5).not_to include(1)
+        }.to fail_matching("expected 5 not to include 1, but it does not respond to `include?`")
+      end
+    end
+
+    context "for an arbitrary object that responds to `include?`" do
+      it 'delegates to `include?`' do
+        container = double("Container")
+        allow(container).to receive(:include?) { |arg| arg == :stuff }
+
+        expect(container).not_to include(:space)
+
+        expect {
+          expect(container).not_to include(:stuff)
+        }.to fail_matching("not to include :stuff")
+      end
+    end
+
+    context "for a string target" do
+      it "passes if target does not include expected" do
+        expect("abc").not_to include("d")
+      end
+
+      it "fails if target includes expected" do
+        expect {
+          expect("abc").not_to include("c")
+        }.to fail_with("expected \"abc\" not to include \"c\"")
+      end
+    end
+
+    context "for an array target" do
+      it "passes if target does not include expected" do
+        expect([1,2,3]).not_to include(4)
+      end
+
+      it "fails if target includes expected" do
+        expect {
+          expect([1,2,3]).not_to include(3)
+        }.to fail_with("expected [1, 2, 3] not to include 3")
+      end
+
+      it 'passes when given differing null doubles' do
+        expect([double.as_null_object]).not_to include(double.as_null_object)
+      end
+
+      it 'fails when given the same null double' do
+        dbl = double.as_null_object
+
+        expect {
+          expect([dbl]).not_to include(dbl)
+        }.to fail_matching("expected [#{dbl.inspect}] not to include")
+      end
+    end
+
+    context "for a hash target" do
+      it 'passes if target does not have the expected as a key' do
+        expect({:other => 'value'}).not_to include(:key)
+      end
+
+      it "fails if target includes expected key" do
+        expect {
+          expect({:key => 'value'}).not_to include(:key)
+        }.to fail_matching(%Q|expected {:key => "value"} not to include :key|)
+      end
+    end
+
+  end
+
+  describe "expect(...).not_to include(with, multiple, args)" do
+    context "for a string target" do
+      it "passes if the target does not include any of the expected" do
+        expect("abc").not_to include("d", "e", "f")
+      end
+
+      it "fails if the target includes all of the expected" do
+        expect {
+          expect("abc").not_to include("c", "a")
+        }.to fail_with('expected "abc" not to include "c" and "a"')
+      end
+
+      it "fails if the target includes some (but not all) of the expected" do
+        expect {
+          expect("abc").not_to include("d", "a")
+        }.to fail_with(%q{expected "abc" not to include "d" and "a"})
+      end
+    end
+
+    context "for a hash target" do
+      it "passes if it does not include any of the expected keys" do
+        expect({ :a => 1, :b => 2 }).not_to include(:c, :d)
+      end
+
+      it "fails if the target includes all of the expected keys" do
+        expect {
+          expect({ :a => 1, :b => 2 }).not_to include(:a, :b)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 2} not to include :a and :b|)
+      end
+
+      it "fails if the target includes some (but not all) of the expected keys" do
+        expect {
+          expect({ :a => 1, :b => 2 }).not_to include(:d, :b)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 2} not to include :d and :b|)
+      end
+    end
+
+    context "for an array target" do
+      it "passes if the target does not include any of the expected" do
+        expect([1, 2, 3]).not_to include(4, 5, 6)
+      end
+
+      it "fails if the target includes all of the expected" do
+        expect {
+          expect([1, 2, 3]).not_to include(3, 1)
+        }.to fail_with(%q{expected [1, 2, 3] not to include 3 and 1})
+      end
+
+      it "fails if the target includes some (but not all) of the expected" do
+        expect {
+          expect([1, 2, 3]).not_to include(4, 1)
+        }.to fail_with(%q{expected [1, 2, 3] not to include 4 and 1})
+      end
+    end
+  end
+
+  describe "expect(...).to include(:key => value)" do
+    context 'for a hash target' do
+      it "passes if target includes the key/value pair" do
+        expect({:key => 'value'}).to include(:key => 'value')
+      end
+
+      it "passes if target includes the key/value pair among others" do
+        expect({:key => 'value', :other => 'different'}).to include(:key => 'value')
+      end
+
+      it "fails if target has a different value for key" do
+        expect {
+          expect({:key => 'different'}).to include(:key => 'value')
+        }.to fail_matching(%Q|expected {:key => "different"} to include {:key => "value"}|)
+      end
+
+      it "fails if target has a different key" do
+        expect {
+          expect({:other => 'value'}).to include(:key => 'value')
+        }.to fail_matching(%Q|expected {:other => "value"} to include {:key => "value"}|)
+      end
+    end
+
+    context 'for a non-hash target' do
+      it "fails if the target does not contain the given hash" do
+        expect {
+          expect(['a', 'b']).to include(:key => 'value')
+        }.to fail_matching(%q|expected ["a", "b"] to include {:key => "value"}|)
+      end
+
+      it "passes if the target contains the given hash" do
+        expect(['a', { :key => 'value' } ]).to include(:key => 'value')
+      end
+    end
+  end
+
+  describe "expect(...).not_to include(:key => value)" do
+    context 'for a hash target' do
+      it "fails if target includes the key/value pair" do
+        expect {
+          expect({:key => 'value'}).not_to include(:key => 'value')
+        }.to fail_matching(%Q|expected {:key => "value"} not to include {:key => "value"}|)
+      end
+
+      it "fails if target includes the key/value pair among others" do
+        expect {
+          expect({:key => 'value', :other => 'different'}).not_to include(:key => 'value')
+        }.to fail_matching(%r|expected #{hash_inspect :key => "value", :other => "different"} not to include \{:key => "value"\}|)
+      end
+
+      it "passes if target has a different value for key" do
+        expect({:key => 'different'}).not_to include(:key => 'value')
+      end
+
+      it "passes if target has a different key" do
+        expect({:other => 'value'}).not_to include(:key => 'value')
+      end
+    end
+
+    context "for a non-hash target" do
+      it "passes if the target does not contain the given hash" do
+        expect(['a', 'b']).not_to include(:key => 'value')
+      end
+
+      it "fails if the target contains the given hash" do
+        expect {
+          expect(['a', { :key => 'value' } ]).not_to include(:key => 'value')
+        }.to fail_matching(%Q|expected ["a", {:key => "value"}] not to include {:key => "value"}|)
+      end
+    end
+  end
+
+  describe "expect(...).to include(:key1 => value1, :key2 => value2)" do
+    context 'for a hash target' do
+      it "passes if target includes the key/value pairs" do
+        expect({:a => 1, :b => 2}).to include(:b => 2, :a => 1)
+      end
+
+      it "passes if target includes the key/value pairs among others" do
+        expect({:a => 1, :c => 3, :b => 2}).to include(:b => 2, :a => 1)
+      end
+
+      it "fails if target has a different value for one of the keys" do
+        expect {
+          expect({:a => 1, :b => 2}).to include(:a => 2, :b => 2)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 2} to include #{hash_inspect :a => 2, :b => 2}|)
+      end
+
+      it "fails if target has a different value for both of the keys" do
+        expect {
+          expect({:a => 1, :b => 1}).to include(:a => 2, :b => 2)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 1} to include #{hash_inspect :a => 2, :b => 2}|)
+      end
+
+      it "fails if target lacks one of the keys" do
+        expect {
+          expect({:a => 1, :b => 1}).to include(:a => 1, :c => 1)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 1} to include #{hash_inspect :a => 1, :c => 1}|)
+      end
+
+      it "fails if target lacks both of the keys" do
+        expect {
+          expect({:a => 1, :b => 1}).to include(:c => 1, :d => 1)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 1} to include #{hash_inspect :c => 1, :d => 1}|)
+      end
+    end
+
+    context 'for a non-hash target' do
+      it "fails if the target does not contain the given hash" do
+        expect {
+          expect(['a', 'b']).to include(:a => 1, :b => 1)
+        }.to fail_matching(%r|expected \["a", "b"\] to include #{hash_inspect :a => 1, :b => 1}|)
+      end
+
+      it "passes if the target contains the given hash" do
+        expect(['a', { :a => 1, :b => 2 } ]).to include(:a => 1, :b => 2)
+      end
+    end
+  end
+
+  describe "expect(...).not_to include(:key1 => value1, :key2 => value2)" do
+    context 'for a hash target' do
+      it "fails if target includes the key/value pairs" do
+        expect {
+          expect({:a => 1, :b => 2}).not_to include(:a => 1, :b => 2)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 2} not to include #{hash_inspect :a => 1, :b => 2}|)
+      end
+
+      it "fails if target includes the key/value pairs among others" do
+        hash = {:a => 1, :b => 2, :c => 3}
+        expect {
+          expect(hash).not_to include(:a => 1, :b => 2)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 2, :c => 3} not to include #{hash_inspect :a => 1, :b => 2}|)
+      end
+
+      it "fails if target has a different value for one of the keys" do
+        expect {
+          expect({:a => 1, :b => 2}).not_to include(:a => 2, :b => 2)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 2} not to include #{hash_inspect :a => 2, :b => 2}|)
+      end
+
+      it "passes if target has a different value for both of the keys" do
+        expect({:a => 1, :b => 1}).not_to include(:a => 2, :b => 2)
+      end
+
+      it "fails if target lacks one of the keys" do
+        expect {
+          expect({:a => 1, :b => 1}).not_to include(:a => 1, :c => 1)
+        }.to fail_matching(%r|expected #{hash_inspect :a => 1, :b => 1} not to include #{hash_inspect :a => 1, :c => 1}|)
+      end
+
+      it "passes if target lacks both of the keys" do
+        expect({:a => 1, :b => 1}).not_to include(:c => 1, :d => 1)
+      end
+    end
+
+    context 'for a non-hash target' do
+      it "passes if the target does not contain the given hash" do
+        expect(['a', 'b']).not_to include(:a => 1, :b => 1)
+      end
+
+      it "fails if the target contains the given hash" do
+        expect {
+          expect(['a', { :a => 1, :b => 2 } ]).not_to include(:a => 1, :b => 2)
+        }.to fail_matching(%r|expected \["a", #{hash_inspect :a => 1, :b => 2}\] not to include #{hash_inspect :a => 1, :b => 2}|)
+      end
+    end
+  end
+
+  describe "Composing matchers with `include`" do
+    RSpec::Matchers.define :a_string_containing do |expected|
+      match do |actual|
+        actual.include?(expected)
+      end
+
+      description do
+        "a string containing '#{expected}'"
+      end
+    end
+
+    describe "expect(array).to include(matcher)" do
+      it "passes when the matcher matches one of the values" do
+        expect([10, 20, 30]).to include( a_value_within(5).of(24) )
+      end
+
+      it 'provides a description' do
+        description = include( a_value_within(5).of(24) ).description
+        expect(description).to eq("include (a value within 5 of 24)")
+      end
+
+      it 'fails with a clear message when the matcher matches none of the values' do
+        expect {
+          expect([10, 30]).to include( a_value_within(5).of(24) )
+        }.to fail_with("expected [10, 30] to include (a value within 5 of 24)")
+      end
+
+      it 'works with comparison matchers' do
+        expect {
+          expect([100, 200]).to include(a_value < 90)
+        }.to fail_with("expected [100, 200] to include (a value < 90)")
+
+        expect([100, 200]).to include(a_value > 150)
+      end
+
+      it 'does not treat an object that only implements #matches? as a matcher' do
+        domain = Struct.new(:domain) do
+          def matches?(url)
+            URI(url).host == self.domain
+          end
+        end
+
+        expect([domain.new("rspec.info")]).to include(domain.new("rspec.info"))
+
+        expect {
+          expect([domain.new("rspec.info")]).to include(domain.new("foo.com"))
+        }.to fail_matching("expected [#{domain.new("rspec.info").inspect}] to include")
+      end
+    end
+
+    describe "expect(array).to include(multiple, matcher, arguments)" do
+      it "passes if target includes items satisfying all matchers" do
+        expect(['foo', 'bar', 'baz']).to include(a_string_containing("ar"), a_string_containing('oo'))
+      end
+
+      it "fails if target does not include an item satisfying any one of the items" do
+        expect {
+          expect(['foo', 'bar', 'baz']).to include(a_string_containing("ar"), a_string_containing("abc"))
+        }.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} to include (a string containing 'ar') and (a string containing 'abc')|)
+      end
+    end
+
+    describe "expect(hash).to include(key => matcher)" do
+      it "passes when the matcher matches" do
+        expect(:a => 12).to include(:a => a_value_within(3).of(10))
+      end
+
+      it 'provides a description' do
+        description = include(:a => a_value_within(3).of(10)).description
+        expect(description).to eq("include {:a => (a value within 3 of 10)}")
+      end
+
+      it "fails with a clear message when the matcher does not match" do
+        expect {
+          expect(:a => 15).to include(:a => a_value_within(3).of(10))
+        }.to fail_matching("expected {:a => 15} to include {:a => (a value within 3 of 10)}")
+      end
+    end
+
+    describe "expect(hash).to include(key_matcher)" do
+      it "passes when the matcher matches a key", :if => (RUBY_VERSION.to_f > 1.8) do
+        expect(:drink => "water", :food => "bread").to include(a_string_matching(/foo/))
+      end
+
+      it 'provides a description' do
+        description = include(a_string_matching(/foo/)).description
+        expect(description).to eq("include (a string matching /foo/)")
+      end
+
+      it 'fails with a clear message when the matcher does not match', :if => (RUBY_VERSION.to_f > 1.8) do
+        expect {
+          expect(:drink => "water", :food => "bread").to include(a_string_matching(/bar/))
+        }.to fail_matching('expected {:drink => "water", :food => "bread"} to include (a string matching /bar/)')
+      end
+    end
+
+    describe "expect(array).not_to include(multiple, matcher, arguments)" do
+      it "passes if none of the target values satisfies any of the matchers" do
+        expect(['foo', 'bar', 'baz']).not_to include(a_string_containing("gh"), a_string_containing('de'))
+      end
+
+      it 'fails if all of the matchers are satisfied by one of the target values' do
+        expect {
+          expect(['foo', 'bar', 'baz']).not_to include(a_string_containing("ar"), a_string_containing('az'))
+        }.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} not to include (a string containing 'ar') and (a string containing 'az')|)
+      end
+
+      it 'fails if the some (but not all) of the matchers are satisifed' do
+        expect {
+          expect(['foo', 'bar', 'baz']).not_to include(a_string_containing("ar"), a_string_containing('bz'))
+        }.to fail_matching(%Q|expected #{['foo', 'bar', 'baz'].inspect} not to include (a string containing 'ar') and (a string containing 'bz')|)
+      end
+    end
+  end
+
+  include RSpec::Matchers::Pretty
+  # We have to use Hash#inspect in examples that have multi-entry
+  # hashes because the #inspect output on 1.8.7 is non-deterministic
+  # due to the fact that hashes are not ordered. So we can't simply
+  # put a literal string for what we expect because it varies.
+  if RUBY_VERSION.to_f == 1.8
+    def hash_inspect(hash)
+      /\{(#{hash.map { |key,value| "#{key.inspect} => #{value.inspect}.*" }.join "|" }){#{hash.size}}\}/
+    end
+  else
+    def hash_inspect(hash)
+      improve_hash_formatting hash.inspect
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/match_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/match_spec.rb
new file mode 100644
index 0000000..3c656dc
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/match_spec.rb
@@ -0,0 +1,100 @@
+RSpec.describe "expect(...).to match(expected)" do
+  it_behaves_like "an RSpec matcher", :valid_value => 'ab', :invalid_value => 'bc' do
+    let(:matcher) { match(/a/) }
+  end
+
+  it "passes when target (String) matches expected (Regexp)" do
+    expect("string").to match(/tri/)
+  end
+
+  it "passes when target (String) matches expected (String)" do
+    expect("string").to match("tri")
+  end
+
+  it "fails when target (String) does not match expected (Regexp)" do
+    expect {
+      expect("string").to match(/rings/)
+    }.to fail
+  end
+
+  it "fails when target (String) does not match expected (String)" do
+    expect {
+      expect("string").to match("rings")
+    }.to fail
+  end
+
+  it "provides message, expected and actual on failure" do
+    matcher = match(/rings/)
+    matcher.matches?("string")
+    expect(matcher.failure_message).to eq "expected \"string\" to match /rings/"
+  end
+
+  it "provides a diff on failure" do
+    allow(RSpec::Matchers.configuration).to receive(:color?).and_return(false)
+
+    failure_message_that_includes_diff = %r%
+\s*Diff:
+\s*@@ -1,2 \+1,2 @@
+\s*-/bar/
+\s*\+"foo"%
+
+    expect { expect("foo").to match(/bar/) }.to fail_with(failure_message_that_includes_diff)
+  end
+
+  context "when passed a data structure with matchers" do
+    it 'passes when the matchers match' do
+      expect(["food", 1.1]).to match([ a_string_matching(/foo/), a_value_within(0.2).of(1) ])
+    end
+
+    it 'fails when the matchers do not match' do
+      expect {
+        expect(["fod", 1.1]).to match([ a_string_matching(/foo/), a_value_within(0.2).of(1) ])
+      }.to fail_with('expected ["fod", 1.1] to match [(a string matching /foo/), (a value within 0.2 of 1)]')
+    end
+
+    it 'provides a description' do
+      description = match([ a_string_matching(/foo/), a_value_within(0.2).of(1) ]).description
+      expect(description).to eq("match [(a string matching /foo/), (a value within 0.2 of 1)]")
+    end
+  end
+end
+
+RSpec.describe "expect(...).not_to match(expected)" do
+  it "passes when target (String) matches does not match (Regexp)" do
+    expect("string").not_to match(/rings/)
+  end
+
+  it "passes when target (String) matches does not match (String)" do
+    expect("string").not_to match("rings")
+  end
+
+  it "fails when target (String) matches expected (Regexp)" do
+    expect {
+      expect("string").not_to match(/tri/)
+    }.to fail
+  end
+
+  it "fails when target (String) matches expected (String)" do
+    expect {
+      expect("string").not_to match("tri")
+    }.to fail
+  end
+
+  it "provides message, expected and actual on failure" do
+    matcher = match(/tri/)
+    matcher.matches?("string")
+    expect(matcher.failure_message_when_negated).to eq "expected \"string\" not to match /tri/"
+  end
+
+  context "when passed a data structure with matchers" do
+    it 'passes when the matchers match' do
+      expect(["food", 1.1]).not_to match([ a_string_matching(/fod/), a_value_within(0.2).of(1) ])
+    end
+
+    it 'fails when the matchers do not match' do
+      expect {
+        expect(["fod", 1.1]).not_to match([ a_string_matching(/fod/), a_value_within(0.2).of(1) ])
+      }.to fail_with('expected ["fod", 1.1] not to match [(a string matching /fod/), (a value within 0.2 of 1)]')
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/operators_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/operators_spec.rb
new file mode 100644
index 0000000..94c0d9e
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/operators_spec.rb
@@ -0,0 +1,250 @@
+class MethodOverrideObject
+  def method
+    :foo
+  end
+end
+
+class MethodMissingObject < Struct.new(:original)
+  undef ==
+
+  def method_missing(name, *args, &block)
+    original.__send__ name, *args, &block
+  end
+end
+
+RSpec.describe "operator matchers", :uses_should do
+  describe "should ==" do
+    it "delegates message to target" do
+      subject = "apple"
+      expect(subject).to receive(:==).with("apple").and_return(true)
+      subject.should == "apple"
+    end
+
+    it "returns true on success" do
+      subject = "apple"
+      (subject.should == "apple").should be_truthy
+    end
+
+    it "fails when target.==(actual) returns false" do
+      subject = "apple"
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: "orange"\n     got: "apple" (using ==)], "orange", "apple")
+      subject.should == "orange"
+    end
+
+    it "works when #method is overriden" do
+      myobj = MethodOverrideObject.new
+      expect {
+        myobj.should == myobj
+      }.to_not raise_error
+    end
+
+    it "works when implemented via method_missing" do
+      obj = Object.new
+
+      myobj = MethodMissingObject.new(obj)
+      (myobj.should == obj).nil? # just to avoid `useless use of == in void context` warning
+      myobj.should_not == Object.new
+    end
+  end
+
+  describe "unsupported operators", :if => RUBY_VERSION.to_f == 1.9 do
+    it "raises an appropriate error for should != expected" do
+      expect {
+        "apple".should != "pear"
+      }.to raise_error(/does not support `should != expected`.  Use `should_not == expected`/)
+    end
+
+    it "raises an appropriate error for should_not != expected" do
+      expect {
+        "apple".should_not != "pear"
+      }.to raise_error(/does not support `should_not != expected`.  Use `should == expected`/)
+    end
+
+    it "raises an appropriate error for should !~ expected" do
+      expect {
+        "apple".should !~ /regex/
+      }.to raise_error(/does not support `should !~ expected`.  Use `should_not =~ expected`/)
+    end
+
+    it "raises an appropriate error for should_not !~ expected" do
+      expect {
+        "apple".should_not !~ /regex/
+      }.to raise_error(/does not support `should_not !~ expected`.  Use `should =~ expected`/)
+    end
+  end
+
+  describe "should_not ==" do
+    it "delegates message to target" do
+      subject = "orange"
+      expect(subject).to receive(:==).with("apple").and_return(false)
+      subject.should_not == "apple"
+    end
+
+    it "returns true on success" do
+      subject = "apple"
+      (subject.should_not == "orange").should be_falsey
+    end
+
+    it "fails when target.==(actual) returns false" do
+      subject = "apple"
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected not: == "apple"\n         got:    "apple"], "apple", "apple")
+      subject.should_not == "apple"
+    end
+  end
+
+  describe "should ===" do
+    it "delegates message to target" do
+      subject = "apple"
+      expect(subject).to receive(:===).with("apple").and_return(true)
+      subject.should === "apple"
+    end
+
+    it "fails when target.===(actual) returns false" do
+      subject = "apple"
+      expect(subject).to receive(:===).with("orange").and_return(false)
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: "orange"\n     got: "apple" (using ===)], "orange", "apple")
+      subject.should === "orange"
+    end
+  end
+
+  describe "should_not ===" do
+    it "delegates message to target" do
+      subject = "orange"
+      expect(subject).to receive(:===).with("apple").and_return(false)
+      subject.should_not === "apple"
+    end
+
+    it "fails when target.===(actual) returns false" do
+      subject = "apple"
+      expect(subject).to receive(:===).with("apple").and_return(true)
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected not: === "apple"\n         got:     "apple"], "apple", "apple")
+      subject.should_not === "apple"
+    end
+  end
+
+  describe "should =~" do
+    it "delegates message to target" do
+      subject = "foo"
+      expect(subject).to receive(:=~).with(/oo/).and_return(true)
+      subject.should =~ /oo/
+    end
+
+    it "fails when target.=~(actual) returns false" do
+      subject = "fu"
+      expect(subject).to receive(:=~).with(/oo/).and_return(false)
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: /oo/\n     got: "fu" (using =~)], /oo/, "fu")
+      subject.should =~ /oo/
+    end
+  end
+
+  describe "should_not =~" do
+    it "delegates message to target" do
+      subject = "fu"
+      expect(subject).to receive(:=~).with(/oo/).and_return(false)
+      subject.should_not =~ /oo/
+    end
+
+    it "fails when target.=~(actual) returns false" do
+      subject = "foo"
+      expect(subject).to receive(:=~).with(/oo/).and_return(true)
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected not: =~ /oo/\n         got:    "foo"], /oo/, "foo")
+      subject.should_not =~ /oo/
+    end
+  end
+
+  describe "should >" do
+    it "passes if > passes" do
+      4.should > 3
+    end
+
+    it "fails if > fails" do
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: > 5\n     got:   4], 5, 4)
+      4.should > 5
+    end
+  end
+
+  describe "should >=" do
+    it "passes if actual == expected" do
+      4.should >= 4
+    end
+
+    it "passes if actual > expected" do
+      4.should >= 3
+    end
+
+    it "fails if > fails" do
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: >= 5\n     got:    4], 5, 4)
+      4.should >= 5
+    end
+  end
+
+  describe "should <" do
+    it "passes if < passes" do
+      4.should < 5
+    end
+
+    it "fails if > fails" do
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: < 3\n     got:   4], 3, 4)
+      4.should < 3
+    end
+  end
+
+  describe "should <=" do
+    it "passes if actual == expected" do
+      4.should <= 4
+    end
+
+    it "passes if actual < expected" do
+      4.should <= 5
+    end
+
+    it "fails if > fails" do
+      expect(RSpec::Expectations).to receive(:fail_with).with(%[expected: <= 3\n     got:    4], 3, 4)
+      4.should <= 3
+    end
+  end
+
+  describe "OperatorMatcher registry" do
+    let(:custom_klass) { Class.new }
+    let(:custom_subklass) { Class.new(custom_klass) }
+
+    after {
+      RSpec::Matchers::BuiltIn::OperatorMatcher.unregister(custom_klass, "=~")
+    }
+
+    it "allows operator matchers to be registered for classes" do
+      RSpec::Matchers::BuiltIn::OperatorMatcher.register(custom_klass, "=~", RSpec::Matchers::BuiltIn::Match)
+      expect(RSpec::Matchers::BuiltIn::OperatorMatcher.get(custom_klass, "=~")).to eq(RSpec::Matchers::BuiltIn::Match)
+    end
+
+    it "considers ancestors when finding an operator matcher" do
+      RSpec::Matchers::BuiltIn::OperatorMatcher.register(custom_klass, "=~", RSpec::Matchers::BuiltIn::Match)
+      expect(RSpec::Matchers::BuiltIn::OperatorMatcher.get(custom_subklass, "=~")).to eq(RSpec::Matchers::BuiltIn::Match)
+    end
+
+    it "returns nil if there is no matcher registered for a class" do
+      expect(RSpec::Matchers::BuiltIn::OperatorMatcher.get(custom_klass, "=~")).to be_nil
+    end
+  end
+
+  describe RSpec::Matchers::BuiltIn::PositiveOperatorMatcher do
+    it "works when the target has implemented #send" do
+      o = Object.new
+      def o.send(*args); raise "DOH! Library developers shouldn't use #send!" end
+      expect {
+        o.should == o
+      }.not_to raise_error
+    end
+  end
+
+  describe RSpec::Matchers::BuiltIn::NegativeOperatorMatcher do
+    it "works when the target has implemented #send" do
+      o = Object.new
+      def o.send(*args); raise "DOH! Library developers shouldn't use #send!" end
+      expect {
+        o.should_not == :foo
+      }.not_to raise_error
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/output_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/output_spec.rb
new file mode 100644
index 0000000..715fd7d
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/output_spec.rb
@@ -0,0 +1,193 @@
+RSpec.shared_examples "output_to_stream" do |stream_name, matcher_method, helper_module|
+  include helper_module
+  extend helper_module
+
+  it_behaves_like("an RSpec matcher", :valid_value => lambda { print_to_stream('foo') }, :invalid_value => lambda {}) do
+    let(:matcher) { output.send(matcher_method) }
+  end
+
+  define_method :matcher do |*args|
+    output(args.first).send(matcher_method)
+  end
+
+  it 'is diffable' do
+    expect(matcher).to be_diffable
+  end
+
+  it 'does not produce warnings when the failure message is accessed first' do
+    expect($VERBOSE).to be_truthy
+    expect { matcher.failure_message }.not_to output.to_stderr
+  end
+
+  context "expect { ... }.to output.#{matcher_method}" do
+    it "passes if the block outputs to #{stream_name}" do
+      expect { print_to_stream 'foo' }.to matcher
+    end
+
+    it "fails if the block does not output to #{stream_name}" do
+      expect {
+        expect { }.to matcher
+      }.to fail_with("expected block to output to #{stream_name}, but did not")
+    end
+  end
+
+  context "expect { ... }.not_to output.#{matcher_method}" do
+    it "passes if the block does not output to #{stream_name}" do
+      expect { }.not_to matcher
+    end
+
+    it "fails if the block outputs to #{stream_name}" do
+      expect {
+        expect { print_to_stream 'foo' }.not_to matcher
+      }.to fail_with("expected block to not output to #{stream_name}, but output \"foo\"")
+    end
+  end
+
+  context "expect { ... }.to output('string').#{matcher_method}" do
+    it "passes if the block outputs that string to #{stream_name}" do
+      expect { print_to_stream 'foo' }.to matcher("foo")
+    end
+
+    it "fails if the block does not output to #{stream_name}" do
+      expect {
+        expect { }.to matcher('foo')
+      }.to fail_with("expected block to output \"foo\" to #{stream_name}, but output nothing")
+    end
+
+    it "fails if the block outputs a different string to #{stream_name}" do
+      expect {
+        expect { print_to_stream 'food' }.to matcher('foo')
+      }.to fail_with("expected block to output \"foo\" to #{stream_name}, but output \"food\"")
+    end
+  end
+
+  context "expect { ... }.to_not output('string').#{matcher_method}" do
+    it "passes if the block outputs a different string to #{stream_name}" do
+      expect { print_to_stream 'food' }.to_not matcher('foo')
+    end
+
+    it "passes if the block does not output to #{stream_name}" do
+      expect { }.to_not matcher('foo')
+    end
+
+    it "fails if the block outputs the same string to #{stream_name}" do
+      expect {
+        expect { print_to_stream 'foo' }.to_not matcher('foo')
+      }.to fail_with("expected block to not output \"foo\" to #{stream_name}, but output \"foo\"")
+    end
+  end
+
+  context "expect { ... }.to output(/regex/).#{matcher_method}" do
+    it "passes if the block outputs a string to #{stream_name} that matches the regex" do
+      expect { print_to_stream 'foo' }.to matcher(/foo/)
+    end
+
+    it "fails if the block does not output to #{stream_name}" do
+      expect {
+        expect { }.to matcher(/foo/)
+      }.to fail_matching("expected block to output /foo/ to #{stream_name}, but output nothing\nDiff")
+    end
+
+    it "fails if the block outputs a string to #{stream_name} that does not match" do
+      expect {
+        expect { print_to_stream 'foo' }.to matcher(/food/)
+      }.to fail_matching("expected block to output /food/ to #{stream_name}, but output \"foo\"\nDiff")
+    end
+  end
+
+  context "expect { ... }.to_not output(/regex/).#{matcher_method}" do
+    it "passes if the block outputs a string to #{stream_name} that does not match the regex" do
+      expect { print_to_stream 'food' }.to_not matcher(/bar/)
+    end
+
+    it "passes if the block does not output to #{stream_name}" do
+      expect { }.to_not matcher(/foo/)
+    end
+
+    it "fails if the block outputs a string to #{stream_name} that matches the regex" do
+      expect {
+        expect { print_to_stream 'foo' }.to_not matcher(/foo/)
+      }.to fail_matching("expected block to not output /foo/ to #{stream_name}, but output \"foo\"\nDiff")
+    end
+  end
+
+  context "expect { ... }.to output(matcher).#{matcher_method}" do
+    it "passes if the block outputs a string to #{stream_name} that passes the given matcher" do
+      expect { print_to_stream 'foo' }.to matcher(a_string_starting_with("f"))
+    end
+
+    it "fails if the block outputs a string to #{stream_name} that does not pass the given matcher" do
+      expect {
+        expect { print_to_stream 'foo' }.to matcher(a_string_starting_with("b"))
+      }.to fail_matching("expected block to output a string starting with \"b\" to #{stream_name}, but output \"foo\"\nDiff")
+    end
+  end
+
+  context "expect { ... }.to_not output(matcher).#{matcher_method}" do
+    it "passes if the block does not output a string to #{stream_name} that passes the given matcher" do
+      expect { print_to_stream 'foo' }.to_not matcher(a_string_starting_with("b"))
+    end
+
+    it "fails if the block outputs a string to #{stream_name} that passes the given matcher" do
+      expect {
+        expect { print_to_stream 'foo' }.to_not matcher(a_string_starting_with("f"))
+      }.to fail_matching("expected block to not output a string starting with \"f\" to #{stream_name}, but output \"foo\"\nDiff")
+    end
+  end
+end
+
+module RSpec
+  module Matchers
+    RSpec.describe "output.to_stderr matcher" do
+      include_examples "output_to_stream", :stderr, :to_stderr, Module.new {
+        def print_to_stream(msg)
+          $stderr.print(msg)
+        end
+      }
+    end
+
+    RSpec.describe "output.to_stdout matcher" do
+      include_examples "output_to_stream", :stdout, :to_stdout, Module.new {
+        def print_to_stream(msg)
+          print(msg)
+        end
+      }
+    end
+
+    RSpec.describe "output.to_stderr_from_any_process matcher" do
+      include_examples "output_to_stream", :stderr, :to_stderr_from_any_process, Module.new {
+        def print_to_stream(msg)
+          if RSpec::Support::OS.windows?
+            system("<nul set /p msg=\"#{msg}\" 1>&2")
+          else
+            system("printf #{msg} 1>&2")
+          end
+        end
+      }
+    end
+
+    RSpec.describe "output.to_stdout_from_any_process matcher" do
+      include_examples "output_to_stream", :stdout, :to_stdout_from_any_process, Module.new {
+        def print_to_stream(msg)
+          if RSpec::Support::OS.windows?
+            system("<nul set /p msg=#{msg}")
+          else
+            system("printf #{msg}")
+          end
+        end
+      }
+    end
+
+    RSpec.describe "output (without `to_stdout` or `to_stderr`)" do
+      it 'raises an error explaining the use is invalid' do
+        expect {
+          expect { print 'foo' }.to output
+        }.to raise_error(/must chain.*to_stdout.*to_stderr/)
+      end
+
+      it 'still provides a description (e.g. when used in a one-liner)' do
+        expect(output("foo").description).to eq('output "foo" to some stream')
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/raise_error_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/raise_error_spec.rb
new file mode 100644
index 0000000..d3df338
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/raise_error_spec.rb
@@ -0,0 +1,446 @@
+RSpec.describe "expect { ... }.to raise_error" do
+  it_behaves_like("an RSpec matcher", :valid_value => lambda { raise "boom" },
+                                      :invalid_value => lambda { }) do
+    let(:matcher) { raise_error }
+  end
+
+  it "passes if anything is raised" do
+    expect {raise}.to raise_error
+  end
+
+  it "passes if an error instance is expected" do
+    s = StandardError.new
+    expect {raise s}.to raise_error(s)
+  end
+
+  it "fails if a different error instance is thrown from the one that is expected" do
+    s = StandardError.new("Error 1")
+    to_raise = StandardError.new("Error 2")
+    expect do
+      expect {raise to_raise}.to raise_error(s)
+    end.to fail_with(Regexp.new("expected #{s.inspect}, got #{to_raise.inspect} with backtrace"))
+  end
+
+  it "passes if an error class is expected and an instance of that class is thrown" do
+    s = StandardError.new :bees
+
+    expect { raise s }.to raise_error(StandardError)
+  end
+
+  it "fails if nothing is raised" do
+    expect {
+      expect {}.to raise_error
+    }.to fail_with("expected Exception but nothing was raised")
+  end
+end
+
+RSpec.describe "raise_exception aliased to raise_error" do
+  it "passes if anything is raised" do
+    expect {raise}.to raise_exception
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error {|err| ... }" do
+  it "passes if there is an error" do
+    ran = false
+    expect { non_existent_method }.to raise_error {|e|
+      ran = true
+    }
+    expect(ran).to be_truthy
+  end
+
+  it "passes the error to the block" do
+    error = nil
+    expect { non_existent_method }.to raise_error {|e|
+      error = e
+    }
+    expect(error).to be_kind_of(NameError)
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error do |err| ... end" do
+  it "passes the error to the block" do
+    error = nil
+    expect { non_existent_method }.to raise_error do |e|
+      error = e
+    end
+    expect(error).to be_kind_of(NameError)
+  end
+end
+
+RSpec.describe "expect { ... }.to(raise_error { |err| ... }) do |err| ... end" do
+  it "passes the error only to the block taken directly by #raise_error" do
+    error_passed_to_curly = nil
+    error_passed_to_do_end = nil
+
+    expect { non_existent_method }.to(raise_error { |e| error_passed_to_curly = e }) do |e|
+      error_passed_to_do_end = e
+    end
+
+    expect(error_passed_to_curly).to be_kind_of(NameError)
+    expect(error_passed_to_do_end).to be_nil
+  end
+end
+
+RSpec.describe "expect { ... }.not_to raise_error" do
+
+  context "with a specific error class" do
+    it "is invalid" do
+      expect {
+        expect {"bees"}.not_to raise_error(RuntimeError)
+      }.to raise_error(/`expect \{ \}\.not_to raise_error\(SpecificErrorClass\)` is not valid/)
+    end
+  end
+
+  context "with no specific error class" do
+    it "passes if nothing is raised" do
+      expect {}.not_to raise_error
+    end
+
+    it "fails if anything is raised" do
+      expect {
+        expect { raise RuntimeError, "example message" }.not_to raise_error
+      }.to fail_with(/expected no Exception, got #<RuntimeError: example message>/)
+    end
+
+    it 'includes the backtrace of the error that was raised in the error message' do
+      expect {
+        expect { raise "boom" }.not_to raise_error
+      }.to raise_error { |e|
+        backtrace_line = "#{File.basename(__FILE__)}:#{__LINE__ - 2}"
+        expect(e.message).to include("with backtrace", backtrace_line)
+      }
+    end
+
+    it 'formats the backtrace using the configured backtrace formatter' do
+      allow(RSpec::Matchers.configuration.backtrace_formatter).
+        to receive(:format_backtrace).
+        and_return("formatted-backtrace")
+
+      expect {
+        expect { raise "boom" }.not_to raise_error
+      }.to raise_error { |e|
+        expect(e.message).to include("with backtrace", "formatted-backtrace")
+      }
+    end
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error(message)" do
+  it "passes if RuntimeError is raised with the right message" do
+    expect {raise 'blah'}.to raise_error('blah')
+  end
+
+  it "passes if RuntimeError is raised with a matching message" do
+    expect {raise 'blah'}.to raise_error(/blah/)
+  end
+
+  it "passes if any other error is raised with the right message" do
+    expect {raise NameError.new('blah')}.to raise_error('blah')
+  end
+
+  it "fails if RuntimeError error is raised with the wrong message" do
+    expect do
+      expect {raise 'blarg'}.to raise_error('blah')
+    end.to fail_with(/expected Exception with \"blah\", got #<RuntimeError: blarg>/)
+  end
+
+  it "fails if any other error is raised with the wrong message" do
+    expect do
+      expect {raise NameError.new('blarg')}.to raise_error('blah')
+    end.to fail_with(/expected Exception with \"blah\", got #<NameError: blarg>/)
+  end
+
+  it 'includes the backtrace of any other error in the failure message' do
+    expect {
+      expect { raise "boom" }.to raise_error(ArgumentError)
+    }.to raise_error { |e|
+      backtrace_line = "#{File.basename(__FILE__)}:#{__LINE__ - 2}"
+      expect(e.message).to include("with backtrace", backtrace_line)
+    }
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error.with_message(message)" do
+  it "raises an argument error if raise_error itself expects a message" do
+    expect {
+      expect { }.to raise_error("bees").with_message("sup")
+    }.to raise_error.with_message(/`expect \{ \}\.to raise_error\(message\)\.with_message\(message\)` is not valid/)
+  end
+
+  it "passes if RuntimeError is raised with the right message" do
+    expect {raise 'blah'}.to raise_error.with_message('blah')
+  end
+
+  it "passes if RuntimeError is raised with a matching message" do
+    expect {raise 'blah'}.to raise_error.with_message(/blah/)
+  end
+
+  it "passes if any other error is raised with the right message" do
+    expect {raise NameError.new('blah')}.to raise_error.with_message('blah')
+  end
+
+  it "fails if RuntimeError error is raised with the wrong message" do
+    expect do
+      expect {raise 'blarg'}.to raise_error.with_message('blah')
+    end.to fail_with(/expected Exception with \"blah\", got #<RuntimeError: blarg>/)
+  end
+
+  it "fails if any other error is raised with the wrong message" do
+    expect do
+      expect {raise NameError.new('blarg')}.to raise_error.with_message('blah')
+    end.to fail_with(/expected Exception with \"blah\", got #<NameError: blarg>/)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to raise_error(message)" do
+  it "is invalid" do
+    expect {
+      expect {raise 'blarg'}.not_to raise_error(/blah/)
+    }.to raise_error(/`expect \{ \}\.not_to raise_error\(message\)` is not valid/)
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error(NamedError)" do
+  it "passes if named error is raised" do
+    expect { non_existent_method }.to raise_error(NameError)
+  end
+
+  it "fails if nothing is raised" do
+    expect {
+      expect { }.to raise_error(NameError)
+    }.to fail_with(/expected NameError but nothing was raised/)
+  end
+
+  it "fails if another error is raised (NameError)" do
+    expect {
+      expect { raise RuntimeError, "example message" }.to raise_error(NameError)
+    }.to fail_with(/expected NameError, got #<RuntimeError: example message>/)
+  end
+
+  it "fails if another error is raised (NameError)" do
+    expect {
+      expect { load "non/existent/file" }.to raise_error(NameError)
+    }.to fail_with(/expected NameError, got #<LoadError/)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to raise_error(NamedError)" do
+  it "is invalid" do
+    expect {
+      expect { }.not_to raise_error(NameError)
+    }.to raise_error(/`expect \{ \}\.not_to raise_error\(SpecificErrorClass\)` is not valid/)
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error(NamedError, error_message) with String" do
+  it "passes if named error is raised with same message" do
+    expect { raise "example message" }.to raise_error(RuntimeError, "example message")
+  end
+
+  it "fails if nothing is raised" do
+    expect {
+      expect {}.to raise_error(RuntimeError, "example message")
+    }.to fail_with(/expected RuntimeError with \"example message\" but nothing was raised/)
+  end
+
+  it "fails if incorrect error is raised" do
+    expect {
+      expect { raise RuntimeError, "example message" }.to raise_error(NameError, "example message")
+    }.to fail_with(/expected NameError with \"example message\", got #<RuntimeError: example message>/)
+  end
+
+  it "fails if correct error is raised with incorrect message" do
+    expect {
+      expect { raise RuntimeError.new("not the example message") }.to raise_error(RuntimeError, "example message")
+    }.to fail_with(/expected RuntimeError with \"example message\", got #<RuntimeError: not the example message/)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to raise_error(NamedError, error_message) with String" do
+  it "is invalid" do
+    expect {
+      expect {}.not_to raise_error(RuntimeError, "example message")
+    }.to raise_error(/`expect \{ \}\.not_to raise_error\(SpecificErrorClass, message\)` is not valid/)
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error(NamedError, error_message) with Regexp" do
+  it "passes if named error is raised with matching message" do
+    expect { raise "example message" }.to raise_error(RuntimeError, /ample mess/)
+  end
+
+  it "fails if nothing is raised" do
+    expect {
+      expect {}.to raise_error(RuntimeError, /ample mess/)
+    }.to fail_with(/expected RuntimeError with message matching \/ample mess\/ but nothing was raised/)
+  end
+
+  it "fails if incorrect error is raised" do
+    expect {
+      expect { raise RuntimeError, "example message" }.to raise_error(NameError, /ample mess/)
+    }.to fail_with(/expected NameError with message matching \/ample mess\/, got #<RuntimeError: example message>/)
+  end
+
+  it "fails if correct error is raised with incorrect message" do
+    expect {
+      expect { raise RuntimeError.new("not the example message") }.to raise_error(RuntimeError, /less than ample mess/)
+    }.to fail_with(/expected RuntimeError with message matching \/less than ample mess\/, got #<RuntimeError: not the example message>/)
+  end
+end
+
+RSpec.describe "expect { ... }.not_to raise_error(NamedError, error_message) with Regexp" do
+  it "is invalid" do
+    expect {
+      expect {}.not_to raise_error(RuntimeError, /ample mess/)
+    }.to raise_error(/`expect \{ \}\.not_to raise_error\(SpecificErrorClass, message\)` is not valid/)
+  end
+end
+
+RSpec.describe "expect { ... }.to raise_error(NamedError, error_message) { |err| ... }" do
+  it "yields exception if named error is raised with same message" do
+    ran = false
+
+    expect {
+      raise "example message"
+    }.to raise_error(RuntimeError, "example message") { |err|
+      ran = true
+      expect(err.class).to eq RuntimeError
+      expect(err.message).to eq "example message"
+    }
+
+    expect(ran).to be(true)
+  end
+
+  it "yielded block fails on it's own right" do
+    ran, passed = false, false
+
+    expect {
+      expect {
+        raise "example message"
+      }.to raise_error(RuntimeError, "example message") { |err|
+        ran = true
+        expect(5).to eq 4
+        passed = true
+      }
+    }.to fail_with(/expected: 4/m)
+
+    expect(ran).to    be_truthy
+    expect(passed).to be_falsey
+  end
+
+  it "does NOT yield exception if no error was thrown" do
+    ran = false
+
+    expect {
+      expect {}.to raise_error(RuntimeError, "example message") { |err|
+        ran = true
+      }
+    }.to fail_with(/expected RuntimeError with \"example message\" but nothing was raised/)
+
+    expect(ran).to eq false
+  end
+
+  it "does not yield exception if error class is not matched" do
+    ran = false
+
+    expect {
+      expect {
+        raise "example message"
+      }.to raise_error(SyntaxError, "example message") { |err|
+        ran = true
+      }
+    }.to fail_with(/expected SyntaxError with \"example message\", got #<RuntimeError: example message>/)
+
+    expect(ran).to eq false
+  end
+
+  it "does NOT yield exception if error message is not matched" do
+    ran = false
+
+    expect {
+      expect {
+        raise "example message"
+      }.to raise_error(RuntimeError, "different message") { |err|
+        ran = true
+      }
+    }.to fail_with(/expected RuntimeError with \"different message\", got #<RuntimeError: example message>/)
+
+    expect(ran).to eq false
+  end
+end
+
+RSpec.describe "expect { ... }.not_to raise_error(NamedError, error_message) { |err| ... }" do
+  it "is invalid" do
+    expect {
+      expect {}.not_to raise_error(RuntimeError, "example message") { |err| }
+    }.to raise_error(/`expect \{ \}\.not_to raise_error\(SpecificErrorClass, message\)` is not valid/)
+  end
+end
+
+RSpec.describe "Composing matchers with `raise_error`" do
+  matcher :an_error_with_attribute do |attr|
+    chain :equal_to do |value|
+      @expected_value = value
+    end
+
+    match do |error|
+      error.__send__(attr) == @expected_value
+    end
+  end
+
+  class FooError < StandardError
+    def foo; :bar; end
+  end
+
+  describe "expect { }.to raise_error(matcher)" do
+    it 'passes when the matcher matches the raised error' do
+      expect { raise FooError }.to raise_error(an_error_with_attribute(:foo).equal_to(:bar))
+    end
+
+    it 'fails with a clear message when the matcher does not match the raised error' do
+      expect {
+        expect { raise FooError }.to raise_error(an_error_with_attribute(:foo).equal_to(3))
+      }.to fail_matching("expected an error with attribute :foo equal to 3, got #<FooError: FooError>")
+    end
+
+    it 'provides a description' do
+      description = raise_error(an_error_with_attribute(:foo).equal_to(3)).description
+      expect(description).to eq("raise an error with attribute :foo equal to 3")
+    end
+  end
+
+  describe "expect { }.to raise_error(ErrorClass, matcher)" do
+    it 'passes when the class and matcher match the raised error' do
+      expect { raise FooError, "food" }.to raise_error(FooError, a_string_including("foo"))
+    end
+
+    it 'fails with a clear message when the matcher does not match the raised error' do
+      expect {
+        expect { raise FooError, "food" }.to raise_error(FooError, a_string_including("bar"))
+      }.to fail_matching('expected FooError with a string including "bar", got #<FooError: food')
+    end
+
+    it 'provides a description' do
+      description = raise_error(FooError, a_string_including("foo")).description
+      expect(description).to eq('raise FooError with a string including "foo"')
+    end
+  end
+
+  describe "expect { }.to raise_error(ErrorClass).with_message(matcher)" do
+    it 'passes when the class and matcher match the raised error' do
+      expect { raise FooError, "food" }.to raise_error(FooError).with_message(a_string_including("foo"))
+    end
+
+    it 'fails with a clear message when the matcher does not match the raised error' do
+      expect {
+        expect { raise FooError, "food" }.to raise_error(FooError).with_message(a_string_including("bar"))
+      }.to fail_matching('expected FooError with a string including "bar", got #<FooError: food')
+    end
+
+    it 'provides a description' do
+      description = raise_error(FooError).with_message(a_string_including("foo")).description
+      expect(description).to eq('raise FooError with a string including "foo"')
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/respond_to_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/respond_to_spec.rb
new file mode 100644
index 0000000..8aedf32
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/respond_to_spec.rb
@@ -0,0 +1,290 @@
+RSpec.describe "expect(...).to respond_to(:sym)" do
+  it_behaves_like "an RSpec matcher", :valid_value => "s", :invalid_value => 5 do
+    let(:matcher) { respond_to(:upcase) }
+  end
+
+  it "passes if target responds to :sym" do
+    expect(Object.new).to respond_to(:methods)
+  end
+
+  it "fails if target does not respond to :sym" do
+    expect {
+      expect("this string").to respond_to(:some_method)
+    }.to fail_with(%q|expected "this string" to respond to :some_method|)
+  end
+end
+
+RSpec.describe "expect(...).to respond_to(:sym).with(1).argument" do
+  it "passes if target responds to :sym with 1 arg" do
+    obj = Object.new
+    def obj.foo(arg); end
+    expect(obj).to respond_to(:foo).with(1).argument
+  end
+
+  it "passes if target responds to any number of arguments" do
+    obj = Object.new
+    def obj.foo(*args); end
+    expect(obj).to respond_to(:foo).with(1).argument
+  end
+
+  it "passes if target responds to one or more arguments" do
+    obj = Object.new
+    def obj.foo(a, *args); end
+    expect(obj).to respond_to(:foo).with(1).argument
+  end
+
+  it "fails if target does not respond to :sym" do
+    obj = Object.new
+    expect {
+      expect(obj).to respond_to(:some_method).with(1).argument
+    }.to fail_with(/expected .* to respond to :some_method/)
+  end
+
+  it "fails if :sym expects 0 args" do
+    obj = Object.new
+    def obj.foo; end
+    expect {
+      expect(obj).to respond_to(:foo).with(1).argument
+    }.to fail_with(/expected #<Object.*> to respond to :foo with 1 argument/)
+  end
+
+  it "fails if :sym expects 2 args" do
+    obj = Object.new
+    def obj.foo(arg, arg2); end
+    expect {
+      expect(obj).to respond_to(:foo).with(1).argument
+    }.to fail_with(/expected #<Object.*> to respond to :foo with 1 argument/)
+  end
+
+  it "fails if :sym expects 2 or more args" do
+    obj = Object.new
+    def obj.foo(arg, arg2, *args); end
+    expect {
+      expect(obj).to respond_to(:foo).with(1).argument
+    }.to fail_with(/expected #<Object.*> to respond to :foo with 1 argument/)
+  end
+end
+
+RSpec.describe "expect(...).to respond_to(message1, message2)" do
+  it "passes if target responds to both messages" do
+    expect(Object.new).to respond_to('methods', 'inspect')
+  end
+
+  it "fails if target does not respond to first message" do
+    expect {
+      expect(Object.new).to respond_to('method_one', 'inspect')
+    }.to fail_with(/expected #<Object:.*> to respond to "method_one"/)
+  end
+
+  it "fails if target does not respond to second message" do
+    expect {
+      expect(Object.new).to respond_to('inspect', 'method_one')
+    }.to fail_with(/expected #<Object:.*> to respond to "method_one"/)
+  end
+
+  it "fails if target does not respond to either message" do
+    expect {
+      expect(Object.new).to respond_to('method_one', 'method_two')
+    }.to fail_with(/expected #<Object:.*> to respond to "method_one", "method_two"/)
+  end
+end
+
+RSpec.describe "expect(...).to respond_to(:sym).with(2).arguments" do
+  it "passes if target responds to :sym with 2 args" do
+    obj = Object.new
+    def obj.foo(a1, a2); end
+    expect(obj).to respond_to(:foo).with(2).arguments
+  end
+
+  it "passes if target responds to any number of arguments" do
+    obj = Object.new
+    def obj.foo(*args); end
+    expect(obj).to respond_to(:foo).with(2).arguments
+  end
+
+  it "passes if target responds to one or more arguments" do
+    obj = Object.new
+    def obj.foo(a, *args); end
+    expect(obj).to respond_to(:foo).with(2).arguments
+  end
+
+  it "passes if target responds to two or more arguments" do
+    obj = Object.new
+    def obj.foo(a, b, *args); end
+    expect(obj).to respond_to(:foo).with(2).arguments
+  end
+
+  it "fails if target does not respond to :sym" do
+    obj = Object.new
+    expect {
+      expect(obj).to respond_to(:some_method).with(2).arguments
+    }.to fail_with(/expected .* to respond to :some_method/)
+  end
+
+  it "fails if :sym expects 0 args" do
+    obj = Object.new
+    def obj.foo; end
+    expect {
+      expect(obj).to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected #<Object.*> to respond to :foo with 2 arguments/)
+  end
+
+  it "fails if :sym expects 1 args" do
+    obj = Object.new
+    def obj.foo(arg); end
+    expect {
+      expect(obj).to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected #<Object.*> to respond to :foo with 2 arguments/)
+  end
+
+  it "fails if :sym expects 3 or more args" do
+    obj = Object.new
+    def obj.foo(arg, arg2, arg3, *args); end
+    expect {
+      expect(obj).to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected #<Object.*> to respond to :foo with 2 arguments/)
+  end
+end
+
+RSpec.describe "expect(...).not_to respond_to(:sym)" do
+  it "passes if target does not respond to :sym" do
+    expect(Object.new).not_to respond_to(:some_method)
+  end
+
+  it "fails if target responds to :sym" do
+    expect {
+      expect(Object.new).not_to respond_to(:methods)
+    }.to fail_with(/expected #<Object:.*> not to respond to :methods/)
+  end
+end
+
+RSpec.describe "expect(...).not_to respond_to(:sym).with(1).argument" do
+  it "fails if target responds to :sym with 1 arg" do
+    obj = Object.new
+    def obj.foo(arg); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(1).argument
+    }.to fail_with(/expected #<Object:.*> not to respond to :foo with 1 argument/)
+  end
+
+  it "fails if target responds to :sym with any number of args" do
+    obj = Object.new
+    def obj.foo(*args); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(1).argument
+    }.to fail_with(/expected #<Object:.*> not to respond to :foo with 1 argument/)
+  end
+
+  it "fails if target responds to :sym with one or more args" do
+    obj = Object.new
+    def obj.foo(a, *args); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(1).argument
+    }.to fail_with(/expected #<Object:.*> not to respond to :foo with 1 argument/)
+  end
+
+  it "passes if target does not respond to :sym" do
+    obj = Object.new
+    expect(obj).not_to respond_to(:some_method).with(1).argument
+  end
+
+  it "passes if :sym expects 0 args" do
+    obj = Object.new
+    def obj.foo; end
+    expect(obj).not_to respond_to(:foo).with(1).argument
+  end
+
+  it "passes if :sym expects 2 args" do
+    obj = Object.new
+    def obj.foo(arg, arg2); end
+    expect(obj).not_to respond_to(:foo).with(1).argument
+  end
+
+  it "passes if :sym expects 2 or more args" do
+    obj = Object.new
+    def obj.foo(arg, arg2, *args); end
+    expect(obj).not_to respond_to(:foo).with(1).argument
+  end
+end
+
+RSpec.describe "expect(...).not_to respond_to(message1, message2)" do
+  it "passes if target does not respond to either message1 or message2" do
+    expect(Object.new).not_to respond_to(:some_method, :some_other_method)
+  end
+
+  it "fails if target responds to message1 but not message2" do
+    expect {
+      expect(Object.new).not_to respond_to(:object_id, :some_method)
+    }.to fail_with(/expected #<Object:.*> not to respond to :object_id/)
+  end
+
+  it "fails if target responds to message2 but not message1" do
+    expect {
+      expect(Object.new).not_to respond_to(:some_method, :object_id)
+    }.to fail_with(/expected #<Object:.*> not to respond to :object_id/)
+  end
+
+  it "fails if target responds to both message1 and message2" do
+    expect {
+      expect(Object.new).not_to respond_to(:class, :object_id)
+    }.to fail_with(/expected #<Object:.*> not to respond to :class, :object_id/)
+  end
+end
+
+RSpec.describe "expect(...).not_to respond_to(:sym).with(2).arguments" do
+  it "fails if target responds to :sym with 2 args" do
+    obj = Object.new
+    def obj.foo(a1, a2); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected .* not to respond to :foo with 2 arguments/)
+  end
+
+  it "fails if target responds to :sym with any number args" do
+    obj = Object.new
+    def obj.foo(*args); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected .* not to respond to :foo with 2 arguments/)
+  end
+
+  it "fails if target responds to :sym with one or more args" do
+    obj = Object.new
+    def obj.foo(a, *args); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected .* not to respond to :foo with 2 arguments/)
+  end
+
+  it "fails if target responds to :sym with two or more args" do
+    obj = Object.new
+    def obj.foo(a, b, *args); end
+    expect {
+      expect(obj).not_to respond_to(:foo).with(2).arguments
+    }.to fail_with(/expected .* not to respond to :foo with 2 arguments/)
+  end
+
+  it "passes if target does not respond to :sym" do
+    obj = Object.new
+    expect(obj).not_to respond_to(:some_method).with(2).arguments
+  end
+
+  it "passes if :sym expects 0 args" do
+    obj = Object.new
+    def obj.foo; end
+    expect(obj).not_to respond_to(:foo).with(2).arguments
+  end
+
+  it "passes if :sym expects 2 args" do
+    obj = Object.new
+    def obj.foo(arg); end
+    expect(obj).not_to respond_to(:foo).with(2).arguments
+  end
+
+  it "passes if :sym expects 3 or more args" do
+    obj = Object.new
+    def obj.foo(a, b, c, *arg); end
+    expect(obj).not_to respond_to(:foo).with(2).arguments
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/satisfy_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/satisfy_spec.rb
new file mode 100644
index 0000000..9cc378e
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/satisfy_spec.rb
@@ -0,0 +1,42 @@
+RSpec.describe "expect(...).to satisfy { block }" do
+  it_behaves_like "an RSpec matcher", :valid_value => true, :invalid_value => false do
+    let(:matcher) { satisfy { |v| v } }
+  end
+
+  it "describes itself" do
+    expect(satisfy.description).to eq("satisfy block")
+  end
+
+  it "passes if block returns true" do
+    expect(true).to satisfy { |val| val }
+    expect(true).to satisfy do |val|
+      val
+    end
+  end
+
+  it "fails if block returns false" do
+    expect {
+      expect(false).to satisfy { |val| val }
+    }.to fail_with("expected false to satisfy block")
+    expect do
+      expect(false).to satisfy do |val|
+        val
+      end
+    end.to fail_with("expected false to satisfy block")
+  end
+end
+
+RSpec.describe "expect(...).not_to satisfy { block }" do
+  it "passes if block returns false" do
+    expect(false).not_to satisfy { |val| val }
+    expect(false).not_to satisfy do |val|
+      val
+    end
+  end
+
+  it "fails if block returns true" do
+    expect {
+      expect(true).not_to satisfy { |val| val }
+    }.to fail_with("expected true not to satisfy block")
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/start_and_end_with_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/start_and_end_with_spec.rb
new file mode 100644
index 0000000..c450a39
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/start_and_end_with_spec.rb
@@ -0,0 +1,415 @@
+RSpec.describe "expect(...).to start_with" do
+  it_behaves_like "an RSpec matcher", :valid_value => "ab", :invalid_value => "bc" do
+    let(:matcher) { start_with("a") }
+  end
+
+  context "with a string" do
+    it "passes if it matches the start of the actual string" do
+      expect("this string").to start_with "this str"
+    end
+
+    it "fails if it does not match the start of the actual string" do
+      expect {
+        expect("this string").to start_with "that str"
+      }.to fail_with("expected \"this string\" to start with \"that str\"")
+    end
+  end
+
+  context "with an array" do
+    it "passes if it is the first element of the array" do
+      expect([0, 1, 2]).to start_with 0
+    end
+
+    it "passes if the first elements of the array match" do
+      expect([0, 1, 2]).to start_with 0, 1
+    end
+
+    it "fails if it does not match the first element of the array" do
+      expect {
+        expect([0, 1, 2]).to start_with 2
+      }.to fail_with("expected [0, 1, 2] to start with 2")
+    end
+
+    it "fails if it the first elements of the array do not match" do
+      expect {
+        expect([0, 1, 2]).to start_with 1, 2
+      }.to fail_with("expected [0, 1, 2] to start with 1 and 2")
+    end
+  end
+
+  context "with an array of strings" do
+    it "passes if given the first element of the array" do
+      expect(%w[ a b c ]).to start_with 'a'
+    end
+
+    it "passes if given the first n of the array" do
+      expect(%w[ a b c ]).to start_with('a', 'b')
+    end
+
+    it 'fails if given the wrong first element of the array' do
+      expect {
+        expect(%w[ a b c ]).to start_with 'z'
+      }.to fail_with('expected ["a", "b", "c"] to start with "z"')
+    end
+  end
+
+  context "with an array of uncustomized structs" do
+    struct = Struct.new(:foo)
+
+    it 'passes if the array ends with a struct equal to the provided struct' do
+      s1 = struct.new(5)
+      s2 = struct.new(5)
+      expect(s1).to eq(s2)
+
+      expect([s1, 10]).to start_with(s2)
+    end
+
+    it 'fails if the array ends with a struct not equal to the provided struct' do
+      s1 = struct.new(5)
+      s2 = struct.new(6)
+      expect(s1).not_to eq(s2)
+
+      expect {
+        expect([s1, 10]).to start_with(s2)
+      }.to fail_matching("expected [#{s1.inspect}, 10] to start with #{s2.inspect}")
+    end
+  end
+
+  context "with an array of structs that have a custom `==` definition" do
+    my_struct = Struct.new(:id, :fluff) do
+      def ==(other)
+        other.is_a?(self.class) && other.id == id
+      end
+    end
+
+    it 'passes if the array ends with a struct equal to the provided struct' do
+      s1 = my_struct.new(1, "foo")
+      s2 = my_struct.new(1, "bar")
+      expect(s1).to eq(s2)
+
+      expect([s1, 10]).to start_with(s2)
+    end
+
+    it 'fails if the array ends with a struct not equal to the provided struct' do
+      s1 = my_struct.new(1, "foo")
+      s2 = my_struct.new(2, "bar")
+      expect(s1).not_to eq(s2)
+
+      expect {
+        expect([s1, 10]).to start_with(s2)
+      }.to fail_matching(%Q{expected [#{s1.inspect}, 10] to start with #{s2.inspect}})
+    end
+  end
+
+  context "with an object that does not respond to :[]" do
+    it "fails with a useful message" do
+      actual = Object.new
+      expect {
+        expect(actual).to start_with 0
+      }.to fail_with("expected #{actual.inspect} to start with 0, but it cannot be indexed using #[]")
+    end
+  end
+
+  context "with a hash" do
+    it "fails with a useful error if trying to match more than one element" do
+      actual   = { :a => 'b', :b => 'b', :c => 'c' }
+      expected = { :a => 'b', :b => 'b' }
+      expect{
+        expect(actual).to start_with(expected)
+      }.to fail_with("expected #{actual.inspect} to start with #{expected.inspect}, but it does not have ordered elements")
+    end
+  end
+
+  describe "composing with other matchers" do
+    it 'passes if the start of an array matches two given matchers' do
+      expect([1.01, "food", 3]).to start_with(a_value_within(0.2).of(1), a_string_matching(/foo/))
+    end
+
+    it 'passes if the start of an array matches one given matcher' do
+      expect([1.01, "food", 3]).to start_with(a_value_within(0.2).of(1))
+    end
+
+    it 'provides a description' do
+      description = start_with(a_value_within(0.1).of(1), a_string_matching(/abc/)).description
+      expect(description).to eq("start with a value within 0.1 of 1 and a string matching /abc/")
+    end
+
+    it 'fails with a clear error message when the matchers do not match' do
+      expect {
+        expect([2.01, "food", 3]).to start_with(a_value_within(0.2).of(1), a_string_matching(/foo/))
+      }.to fail_with('expected [2.01, "food", 3] to start with a value within 0.2 of 1 and a string matching /foo/')
+    end
+  end
+end
+
+RSpec.describe "expect(...).not_to start_with" do
+  context "with a string" do
+    it "passes if it does not match the start of the actual string" do
+      expect("this string").not_to start_with "that str"
+    end
+
+    it "fails if it does match the start of the actual string" do
+      expect {
+        expect("this string").not_to start_with "this str"
+      }.to fail_with("expected \"this string\" not to start with \"this str\"")
+    end
+  end
+
+  context "with an array" do
+    it "passes if it is not the first element of the array" do
+      expect([0, 1, 2]).not_to start_with 2
+    end
+
+    it "passes if the first elements of the array do not match" do
+      expect([0, 1, 2]).not_to start_with 1, 2
+    end
+
+    it "fails if it matches the first element of the array" do
+      expect {
+        expect([0, 1, 2]).not_to start_with 0
+      }.to fail_with("expected [0, 1, 2] not to start with 0")
+    end
+
+    it "fails if it the first elements of the array match" do
+      expect {
+        expect([0, 1, 2]).not_to start_with 0, 1
+      }.to fail_with("expected [0, 1, 2] not to start with 0 and 1")
+    end
+  end
+
+  context "with an array of strings" do
+    it "fails if given the first element of the array" do
+      expect {
+        expect(%w[ a b c ]).not_to start_with 'a'
+      }.to fail_with('expected ["a", "b", "c"] not to start with "a"')
+    end
+
+    it "fails if given the first n of the array" do
+      expect {
+        expect(%w[ a b c ]).not_to start_with('a', 'b')
+      }.to fail_with('expected ["a", "b", "c"] not to start with "a" and "b"')
+    end
+
+    it 'passes if given the wrong first element of the array' do
+      expect(%w[ a b c ]).not_to start_with 'z'
+    end
+  end
+
+  it 'can pass when composed with another matcher' do
+    expect(["a"]).not_to start_with(a_string_matching(/bar/))
+  end
+
+  it 'can fail when composed with another matcher' do
+    expect {
+      expect(["a"]).not_to start_with(a_string_matching(/a/))
+    }.to fail_with('expected ["a"] not to start with a string matching /a/')
+  end
+end
+
+RSpec.describe "expect(...).to end_with" do
+  it_behaves_like "an RSpec matcher", :valid_value => "ab", :invalid_value => "bc" do
+    let(:matcher) { end_with("b") }
+  end
+
+  context "with a string" do
+    it "passes if it matches the end of the actual string" do
+      expect("this string").to end_with "is string"
+    end
+
+    it "fails if it does not match the end of the actual string" do
+      expect {
+        expect("this string").to end_with "is stringy"
+      }.to fail_with("expected \"this string\" to end with \"is stringy\"")
+    end
+  end
+
+  context "with an array" do
+    it "passes if it is the last element of the array" do
+      expect([0, 1, 2]).to end_with 2
+    end
+
+    it "passes if the last elements of the array match" do
+      expect([0, 1, 2]).to end_with [1, 2]
+    end
+
+    it "fails if it does not match the last element of the array" do
+      expect {
+        expect([0, 1, 2]).to end_with 1
+      }.to fail_with("expected [0, 1, 2] to end with 1")
+    end
+
+    it "fails if it the last elements of the array do not match" do
+      expect {
+        expect([0, 1, 2]).to end_with [0, 1]
+      }.to fail_with("expected [0, 1, 2] to end with 0 and 1")
+    end
+  end
+
+  context "with an array of strings" do
+    it "passes if given the last element of the array" do
+      expect(%w[ a b c ]).to end_with 'c'
+    end
+
+    it "passes if given the last n of the array" do
+      expect(%w[ a b c ]).to end_with('b', 'c')
+    end
+
+    it 'fails if given the wrong last element of the array' do
+      expect {
+        expect(%w[ a b c ]).to end_with 'z'
+      }.to fail_with('expected ["a", "b", "c"] to end with "z"')
+    end
+  end
+
+  context "with an array of uncustomized structs" do
+    struct = Struct.new(:foo)
+
+    it 'passes if the array ends with a struct equal to the provided struct' do
+      s1 = struct.new(5)
+      s2 = struct.new(5)
+      expect(s1).to eq(s2)
+
+      expect([10, s1]).to end_with(s2)
+    end
+
+    it 'fails if the array ends with a struct not equal to the provided struct' do
+      s1 = struct.new(5)
+      s2 = struct.new(6)
+      expect(s1).not_to eq(s2)
+
+      expect {
+        expect([10, s1]).to end_with(s2)
+      }.to fail_matching("expected [10, #{s1.inspect}] to end with #{s2.inspect}")
+    end
+  end
+
+  context "with an array of structs that have a custom `==` definition" do
+    my_struct = Struct.new(:id, :fluff) do
+      def ==(other)
+        other.is_a?(self.class) && other.id == id
+      end
+    end
+
+    it 'passes if the array ends with a struct equal to the provided struct' do
+      s1 = my_struct.new(1, "foo")
+      s2 = my_struct.new(1, "bar")
+      expect(s1).to eq(s2)
+
+      expect([10, s1]).to end_with(s2)
+    end
+
+    it 'fails if the array ends with a struct not equal to the provided struct' do
+      s1 = my_struct.new(1, "foo")
+      s2 = my_struct.new(2, "bar")
+      expect(s1).not_to eq(s2)
+
+      expect {
+        expect([10, s1]).to end_with(s2)
+      }.to fail_matching(%Q{expected [10, #{s1.inspect}] to end with #{s2.inspect}})
+    end
+  end
+
+  context "with an object that does not respond to :[]" do
+    it "fails with a useful message" do
+      actual = Object.new
+      expect {
+        expect(actual).to end_with 0
+      }.to fail_with("expected #{actual.inspect} to end with 0, but it cannot be indexed using #[]")
+    end
+  end
+
+  context "with a hash" do
+    it "raises an ArgumentError if trying to match more than one element" do
+      actual   = { :a => 'b', :b => 'b', :c => 'c' }
+      expected = { :a => 'b', :b => 'b' }
+      expect{
+        expect(actual).to end_with(expected)
+      }.to fail_with("expected #{actual.inspect} to end with #{expected.inspect}, but it does not have ordered elements")
+    end
+  end
+
+  describe "composing with other matchers" do
+    it 'passes if the end of an array matches two given matchers' do
+      expect([3, "food", 1.1]).to end_with(a_string_matching(/foo/), a_value_within(0.2).of(1))
+    end
+
+    it 'passes if the end of an array matches one given matcher' do
+      expect([3, "food", 1.1]).to end_with(a_value_within(0.2).of(1))
+    end
+
+    it 'provides a description' do
+      description = end_with(a_value_within(0.1).of(1), a_string_matching(/abc/)).description
+      expect(description).to eq("end with a value within 0.1 of 1 and a string matching /abc/")
+    end
+
+    it 'fails with a clear error message when the matchers do not match' do
+      expect {
+        expect([2.01, 3, "food"]).to end_with(a_value_within(0.2).of(1), a_string_matching(/foo/))
+      }.to fail_with('expected [2.01, 3, "food"] to end with a value within 0.2 of 1 and a string matching /foo/')
+    end
+  end
+end
+
+RSpec.describe "expect(...).not_to end_with" do
+  context "with a sting" do
+    it "passes if it does not match the end of the actual string" do
+      expect("this string").not_to end_with "stringy"
+    end
+
+    it "fails if it matches the end of the actual string" do
+      expect {
+        expect("this string").not_to end_with "string"
+      }.to fail_with("expected \"this string\" not to end with \"string\"")
+    end
+  end
+
+  context "an array" do
+    it "passes if it is not the last element of the array" do
+      expect([0, 1, 2]).not_to end_with 1
+    end
+
+    it "passes if the last elements of the array do not match" do
+      expect([0, 1, 2]).not_to end_with [0, 1]
+    end
+
+    it "fails if it matches the last element of the array" do
+      expect {
+        expect([0, 1, 2]).not_to end_with 2
+      }.to fail_with("expected [0, 1, 2] not to end with 2")
+    end
+
+    it "fails if it the last elements of the array match" do
+      expect {
+        expect([0, 1, 2]).not_to end_with [1, 2]
+      }.to fail_with("expected [0, 1, 2] not to end with 1 and 2")
+    end
+  end
+
+  context "with an array of strings" do
+    it "fails if given the last element of the array" do
+      expect {
+        expect(%w[ a b c ]).not_to end_with 'c'
+      }.to fail_with('expected ["a", "b", "c"] not to end with "c"')
+    end
+
+    it "fails if given the last n of the array" do
+      expect {
+        expect(%w[ a b c ]).not_to end_with('b', 'c')
+      }.to fail_with('expected ["a", "b", "c"] not to end with "b" and "c"')
+    end
+
+    it 'passes if given the wrong last element of the array' do
+      expect(%w[ a b c ]).not_to end_with 'z'
+    end
+  end
+
+  it 'can pass when composed with another matcher' do
+    expect(["a"]).not_to end_with(a_string_matching(/bar/))
+  end
+
+  it 'can fail when composed with another matcher' do
+    expect {
+      expect(["a"]).not_to end_with(a_string_matching(/a/))
+    }.to fail_with('expected ["a"] not to end with a string matching /a/')
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/throw_symbol_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/throw_symbol_spec.rb
new file mode 100644
index 0000000..a6cf461
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/throw_symbol_spec.rb
@@ -0,0 +1,133 @@
+module RSpec::Matchers::BuiltIn
+  RSpec.describe ThrowSymbol do
+    it_behaves_like("an RSpec matcher", :valid_value => lambda { throw :foo },
+                                        :invalid_value => lambda { }) do
+      let(:matcher) { throw_symbol(:foo) }
+    end
+
+    describe "with no args" do
+      before(:example) { @matcher = throw_symbol }
+
+      it "matches if any Symbol is thrown" do
+        expect(@matcher.matches?(lambda{ throw :sym })).to be_truthy
+      end
+      it "matches if any Symbol is thrown with an arg" do
+        expect(@matcher.matches?(lambda{ throw :sym, "argument" })).to be_truthy
+      end
+      it "does not match if no Symbol is thrown" do
+        expect(@matcher.matches?(lambda{ })).to be_falsey
+      end
+      it "provides a failure message" do
+        @matcher.matches?(lambda{})
+        expect(@matcher.failure_message).to eq "expected a Symbol to be thrown, got nothing"
+      end
+      it "provides a negative failure message" do
+        @matcher.matches?(lambda{ throw :sym})
+        expect(@matcher.failure_message_when_negated).to eq "expected no Symbol to be thrown, got :sym"
+      end
+    end
+
+    describe "with a symbol" do
+      before(:example) { @matcher = throw_symbol(:sym) }
+
+      it "matches if correct Symbol is thrown" do
+        expect(@matcher.matches?(lambda{ throw :sym })).to be_truthy
+      end
+      it "matches if correct Symbol is thrown with an arg" do
+        expect(@matcher.matches?(lambda{ throw :sym, "argument" })).to be_truthy
+      end
+      it "does not match if no Symbol is thrown" do
+        expect(@matcher.matches?(lambda{ })).to be_falsey
+      end
+      it "does not match if correct Symbol is thrown" do
+        expect(@matcher.matches?(lambda{ throw :other_sym })).to be_falsey
+      end
+      it "provides a failure message when no Symbol is thrown" do
+        @matcher.matches?(lambda{})
+        expect(@matcher.failure_message).to eq "expected :sym to be thrown, got nothing"
+      end
+      it "provides a failure message when wrong Symbol is thrown" do
+        @matcher.matches?(lambda{ throw :other_sym })
+        expect(@matcher.failure_message).to eq "expected :sym to be thrown, got :other_sym"
+      end
+      it "provides a negative failure message" do
+        @matcher.matches?(lambda{ throw :sym })
+        expect(@matcher.failure_message_when_negated).to eq "expected :sym not to be thrown, got :sym"
+      end
+      it "only matches NameErrors raised by uncaught throws" do
+        expect {
+          expect(@matcher.matches?(lambda{ sym })).to be_falsey
+        }.to raise_error(NameError)
+      end
+    end
+
+    describe "with a symbol and an arg" do
+      before(:example) { @matcher = throw_symbol(:sym, "a") }
+
+      it "matches if correct Symbol and args are thrown" do
+        expect(@matcher.matches?(lambda{ throw :sym, "a" })).to be_truthy
+      end
+      it "does not match if nothing is thrown" do
+        expect(@matcher.matches?(lambda{ })).to be_falsey
+      end
+      it "does not match if other Symbol is thrown" do
+        expect(@matcher.matches?(lambda{ throw :other_sym, "a" })).to be_falsey
+      end
+      it "does not match if no arg is thrown" do
+        expect(@matcher.matches?(lambda{ throw :sym })).to be_falsey
+      end
+      it "does not match if wrong arg is thrown" do
+        expect(@matcher.matches?(lambda{ throw :sym, "b" })).to be_falsey
+      end
+      it "provides a failure message when no Symbol is thrown" do
+        @matcher.matches?(lambda{})
+        expect(@matcher.failure_message).to eq %q[expected :sym with "a" to be thrown, got nothing]
+      end
+      it "provides a failure message when wrong Symbol is thrown" do
+        @matcher.matches?(lambda{ throw :other_sym })
+        expect(@matcher.failure_message).to eq %q[expected :sym with "a" to be thrown, got :other_sym]
+      end
+      it "provides a failure message when wrong arg is thrown" do
+        @matcher.matches?(lambda{ throw :sym, "b" })
+        expect(@matcher.failure_message).to eq %q[expected :sym with "a" to be thrown, got :sym with "b"]
+      end
+      it "provides a failure message when no arg is thrown" do
+        @matcher.matches?(lambda{ throw :sym })
+        expect(@matcher.failure_message).to eq %q[expected :sym with "a" to be thrown, got :sym with no argument]
+      end
+      it "provides a negative failure message" do
+        @matcher.matches?(lambda{ throw :sym })
+        expect(@matcher.failure_message_when_negated).to eq %q[expected :sym with "a" not to be thrown, got :sym with no argument]
+      end
+      it "only matches NameErrors raised by uncaught throws" do
+        expect {
+          expect(@matcher.matches?(lambda{ sym })).to be_falsey
+        }.to raise_error(NameError)
+      end
+      it "raises other errors" do
+        expect {
+          @matcher.matches?(lambda { raise "Boom" })
+        }.to raise_error(/Boom/)
+      end
+    end
+
+    describe "composing with other matchers" do
+      it 'passes when the matcher matches the thrown arg' do
+        expect {
+          throw :foo, "bar"
+        }.to throw_symbol(:foo, a_string_matching(/bar/))
+      end
+
+      it 'fails when the matcher does not match the thrown arg' do
+        expect {
+          expect { throw :foo, "bar" }.to throw_symbol(:foo, a_string_matching(/foo/))
+        }.to fail_with('expected :foo with a string matching /foo/ to be thrown, got :foo with "bar"')
+      end
+
+      it 'provides a description' do
+        description = throw_symbol(:foo, a_string_matching(/bar/)).description
+        expect(description).to eq("throw :foo with a string matching /bar/")
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/built_in/yield_spec.rb b/rspec-expectations/spec/rspec/matchers/built_in/yield_spec.rb
new file mode 100644
index 0000000..6f270e6
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/built_in/yield_spec.rb
@@ -0,0 +1,648 @@
+module YieldHelpers
+  # these helpers are prefixed with an underscore to prevent
+  # collisions with the matchers (some of which have the same names)
+  def _dont_yield
+  end
+
+  def _yield_with_no_args
+    yield
+  end
+
+  def _yield_with_args(*args)
+    yield(*args)
+  end
+end
+
+class InstanceEvaler
+
+  def yield_with_no_args(&block)
+    instance_exec(&block)
+  end
+
+  def yield_with_args(*args, &block)
+    instance_exec(*args, &block)
+  end
+
+  def each_arg(*args, &block)
+    args.each do |arg|
+      instance_exec(arg, &block)
+    end
+  end
+end
+
+RSpec.describe "yield_control matcher" do
+  include YieldHelpers
+  extend  YieldHelpers
+
+  it_behaves_like "an RSpec matcher",
+      :valid_value => lambda { |b| _yield_with_no_args(&b) },
+      :invalid_value => lambda { |b| _dont_yield(&b) } do
+    let(:matcher) { yield_control }
+  end
+
+  it 'has a description' do
+    expect(yield_control.description).to eq("yield control")
+  end
+
+  describe "expect {...}.to yield_control" do
+    it 'passes if the block yields, regardless of the number of yielded arguments or the number of yields' do
+      expect { |b| _yield_with_no_args(&b) }.to yield_control
+      expect { |b| _yield_with_args(1, 2, &b) }.to yield_control
+      expect { |b| 1.upto(10, &b) }.to yield_control
+    end
+
+    it 'passes if the block yields using instance_exec' do
+      expect { |b| InstanceEvaler.new.yield_with_no_args(&b) }.to yield_control
+    end
+
+    it 'fails if the block does not yield' do
+      expect {
+        expect { |b| _dont_yield(&b) }.to yield_control
+      }.to fail_with(/expected given block to yield control/)
+    end
+
+    it 'does not return a meaningful value from the block' do
+      val = nil
+      expect { |b| val = _yield_with_args(&b) }.to yield_control
+      expect(val).to be_nil
+    end
+
+    context "with exact count" do
+      it 'fails if the block yields wrong number of times' do
+        expect {
+          expect { |b| [1, 2].each(&b) }.to yield_control.once
+        }.to fail_with(/expected given block to yield control once but yielded twice/)
+
+        expect {
+          expect { |b| [1, 2, 3].each(&b) }.to yield_control.twice
+        }.to fail_with(/expected given block to yield control twice but yielded 3 times/)
+
+        expect {
+          expect { |b| [1, 2].each(&b) }.to yield_control.thrice
+        }.to fail_with(/expected given block to yield control 3 times/)
+      end
+
+      it 'passes if the block yields the specified number of times' do
+        expect { |b| [1].each(&b) }.to yield_control.once
+        expect { |b| [1, 2].each(&b) }.to yield_control.twice
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.thrice
+        expect { |b| [1, 2, 3, 4].each(&b) }.to yield_control.exactly(4).times
+      end
+    end
+
+    context "with at_least count" do
+      it 'passes if the block yields the given number of times' do
+        expect { |b| [1, 2].each(&b) }.to yield_control.at_least(2).times
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_least(3).times
+      end
+
+      it 'passes if the block yields more times' do
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_least(2).times
+        expect { |b| [1, 2, 3, 4].each(&b) }.to yield_control.at_least(3).times
+      end
+
+      it 'allows :once, :twice, and :thrice to be passed as counts' do
+        expect { |b| [1].each(&b) }.to yield_control.at_least(:once)
+        expect { |b| [1, 2].each(&b) }.to yield_control.at_least(:once)
+
+        expect {
+          expect { |b| [].each(&b) }.to yield_control.at_least(:once)
+        }.to fail_with(/at least once/)
+
+        expect { |b| [1, 2].each(&b) }.to yield_control.at_least(:twice)
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_least(:twice)
+
+        expect {
+          expect { |b| [1].each(&b) }.to yield_control.at_least(:twice)
+        }.to fail_with(/at least twice/)
+
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_least(:thrice)
+        expect { |b| [1, 2, 3, 4].each(&b) }.to yield_control.at_least(:thrice)
+
+        expect {
+          expect { |b| [1, 2].each(&b) }.to yield_control.at_least(:thrice)
+        }.to fail_with(/at least 3 times/)
+      end
+
+      it 'fails if the block yields too few times' do
+        expect {
+          expect { |b| _yield_with_no_args(&b) }.to yield_control.at_least(2).times
+        }.to fail_with(/expected given block to yield control at least twice/)
+      end
+    end
+
+    context "with at_most count" do
+      it 'passes if the block yields the given number of times' do
+        expect { |b| [1, 2].each(&b) }.to yield_control.at_most(2).times
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_most(3).times
+      end
+
+      it 'passes if the block yields fewer times' do
+        expect { |b| [1, 2].each(&b) }.to yield_control.at_most(3).times
+      end
+
+      it 'allows :once, :twice, and :thrice to be passed as counts' do
+        expect { |b| [1].each(&b) }.to yield_control.at_most(:once)
+
+        expect {
+          expect { |b| [1, 2].each(&b) }.to yield_control.at_most(:once)
+        }.to fail_with(/expected given block to yield control at most once/)
+
+        expect { |b| [1, 2].each(&b) }.to yield_control.at_most(:twice)
+
+        expect {
+          expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_most(:twice)
+        }.to fail_with(/expected given block to yield control at most twice/)
+
+        expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_most(:thrice)
+
+        expect {
+          expect { |b| [1, 2, 3, 4].each(&b) }.to yield_control.at_most(:thrice)
+        }.to fail_with(/expected given block to yield control at most 3 times/)
+      end
+
+      it 'fails if the block yields too many times' do
+        expect {
+          expect { |b| [1, 2, 3].each(&b) }.to yield_control.at_most(2).times
+        }.to fail_with(/expected given block to yield control at most twice/)
+      end
+    end
+  end
+
+  describe "expect {...}.not_to yield_control" do
+    it 'passes if the block does not yield' do
+      expect { |b| _dont_yield(&b) }.not_to yield_control
+    end
+
+    it 'fails if the block does yield' do
+      expect {
+        expect { |b| _yield_with_no_args(&b) }.not_to yield_control
+      }.to fail_with(/expected given block not to yield control/)
+    end
+
+    it 'fails if the expect block does not accept an argument', :if => (RUBY_VERSION.to_f > 1.8) do
+      expect {
+        expect { }.not_to yield_control
+      }.to raise_error(/expect block must accept an argument/)
+    end
+
+    it 'still works when the block uses an arg splat' do
+      expect { |*args| _dont_yield(&args.first) }.not_to yield_control
+    end
+
+    it 'raises an error if the expect block arg is not passed to a method as a block' do
+      expect {
+        expect { |b| }.not_to yield_control
+      }.to raise_error(/must pass the argument.*as a block/)
+    end
+  end
+end
+
+RSpec.describe "yield_with_no_args matcher" do
+  include YieldHelpers
+  extend  YieldHelpers
+
+  it_behaves_like "an RSpec matcher",
+      :valid_value => lambda { |b| _yield_with_no_args(&b) },
+      :invalid_value => lambda { |b| _dont_yield(&b) } do
+    let(:matcher) { yield_with_no_args }
+  end
+
+  it 'has a description' do
+    expect(yield_with_no_args.description).to eq("yield with no args")
+  end
+
+  it 'does not return a meaningful value from the block' do
+    val = nil
+    expect { |b| val = _yield_with_no_args(&b) }.to yield_with_no_args
+    expect(val).to be_nil
+  end
+
+  describe "expect {...}.to yield_with_no_args" do
+    it 'passes if the block yields with no args' do
+      expect { |b| _yield_with_no_args(&b) }.to yield_with_no_args
+    end
+
+    it 'passes if the block yields with no args using instance_exec' do
+      expect { |b| InstanceEvaler.new.yield_with_no_args(&b) }.to yield_with_no_args
+    end
+
+    it 'fails if the block does not yield' do
+      expect {
+        expect { |b| _dont_yield(&b) }.to yield_with_no_args
+      }.to fail_with(/expected given block to yield with no arguments, but did not yield/)
+    end
+
+    it 'fails if the block yields with args' do
+      expect {
+        expect { |b| _yield_with_args(1, &b) }.to yield_with_no_args
+      }.to fail_with(/expected given block to yield with no arguments, but yielded with arguments/)
+    end
+
+    it 'fails if the block yields with arg false' do
+      expect {
+        expect { |b| _yield_with_args(false, &b) }.to yield_with_no_args
+      }.to fail_with(/expected given block to yield with no arguments, but yielded with arguments/)
+    end
+
+    it 'raises an error if it yields multiple times' do
+      expect {
+        expect { |b| [1, 2].each(&b) }.to yield_with_no_args
+      }.to raise_error(/not designed.*yields multiple times/)
+    end
+  end
+
+  describe "expect {...}.not_to yield_with_no_args" do
+    it "passes if the block does not yield" do
+      expect { |b| _dont_yield(&b) }.not_to yield_with_no_args
+    end
+
+    it "passes if the block yields with args" do
+      expect { |b| _yield_with_args(1, &b) }.not_to yield_with_no_args
+    end
+
+    it "fails if the block yields with no args" do
+      expect {
+        expect { |b| _yield_with_no_args(&b) }.not_to yield_with_no_args
+      }.to fail_with(/expected given block not to yield with no arguments, but did/)
+    end
+
+    it 'fails if the expect block does not accept an argument', :if => (RUBY_VERSION.to_f > 1.8) do
+      expect {
+        expect { }.not_to yield_with_no_args
+      }.to raise_error(/expect block must accept an argument/)
+    end
+
+    it 'raises an error if the expect block arg is not passed to a method as a block' do
+      expect {
+        expect { |b| }.not_to yield_with_no_args
+      }.to raise_error(/must pass the argument.*as a block/)
+    end
+  end
+end
+
+RSpec.describe "yield_with_args matcher" do
+  include YieldHelpers
+  extend  YieldHelpers
+
+  it_behaves_like "an RSpec matcher",
+      :valid_value => lambda { |b| _yield_with_args(1, &b) },
+      :invalid_value => lambda { |b| _dont_yield(&b) } do
+    let(:matcher) { yield_with_args }
+  end
+
+  it 'has a description' do
+    expect(yield_with_args.description).to eq("yield with args")
+    expect(yield_with_args(1, 3).description).to eq("yield with args(1, 3)")
+    expect(yield_with_args(false).description).to eq("yield with args(false)")
+  end
+
+  it 'does not return a meaningful value from the block' do
+    val = nil
+    expect { |b| val = _yield_with_args(1, &b) }.to yield_with_args(1)
+    expect(val).to be_nil
+  end
+
+  describe "expect {...}.to yield_with_args" do
+    it 'passes if the block yields with arguments' do
+      expect { |b| _yield_with_args(1, &b) }.to yield_with_args
+    end
+
+    it 'fails if the block does not yield' do
+      expect {
+        expect { |b| _dont_yield(&b) }.to yield_with_args
+      }.to fail_with(/expected given block to yield with arguments, but did not yield/)
+    end
+
+    it 'fails if the block yields with no arguments' do
+      expect {
+        expect { |b| _yield_with_no_args(&b) }.to yield_with_args
+      }.to fail_with(/expected given block to yield with arguments, but yielded with no arguments/)
+    end
+
+    it 'raises an error if it yields multiple times' do
+      expect {
+        expect { |b| [1, 2].each(&b) }.to yield_with_args
+      }.to raise_error(/not designed.*yields multiple times/)
+    end
+  end
+
+  describe "expect {...}.not_to yield_with_args" do
+    it 'fails if the block yields with arguments' do
+      expect {
+        expect { |b| _yield_with_args(1, &b) }.not_to yield_with_args
+      }.to fail_with(/expected given block not to yield with arguments, but did/)
+    end
+
+    it 'passes if the block does not yield' do
+      expect { |b| _dont_yield(&b) }.not_to yield_with_args
+    end
+
+    it 'passes if the block yields with no arguments' do
+      expect { |b| _yield_with_no_args(&b) }.not_to yield_with_args
+    end
+
+    it 'fails if the expect block does not accept an argument', :if => (RUBY_VERSION.to_f > 1.8) do
+      expect {
+        expect { }.not_to yield_with_args
+      }.to raise_error(/expect block must accept an argument/)
+    end
+
+    it 'raises an error if the expect block arg is not passed to a method as a block' do
+      expect {
+        expect { |b| }.not_to yield_with_args
+      }.to raise_error(/must pass the argument.*as a block/)
+    end
+  end
+
+  describe "expect {...}.to yield_with_args(3, 17)" do
+    it 'passes if the block yields with the given arguments' do
+      expect { |b| _yield_with_args(3, 17, &b) }.to yield_with_args(3, 17)
+    end
+
+    it 'passes if the block yields with the given arguments using instance_exec' do
+      expect { |b| InstanceEvaler.new.yield_with_args(3, 17, &b) }.to yield_with_args(3, 17)
+    end
+
+    it 'fails if the block does not yield' do
+      expect {
+        expect { |b| _dont_yield(&b) }.to yield_with_args(3, 17)
+      }.to fail_with(/expected given block to yield with arguments, but did not yield/)
+    end
+
+    it 'fails if the block yields with no arguments' do
+      expect {
+        expect { |b| _yield_with_no_args(&b) }.to yield_with_args(3, 17)
+      }.to fail_with(/expected given block to yield with arguments, but yielded with unexpected arguments/)
+    end
+
+    it 'fails if the block yields with different arguments' do
+      expect {
+        expect { |b| _yield_with_args("a", "b", &b) }.to yield_with_args("a", "c")
+      }.to fail_with(/expected given block to yield with arguments, but yielded with unexpected arguments/)
+    end
+  end
+
+  describe "expect {...}.to yield_with_args(matcher, matcher)" do
+    it 'passes when the matchers match the args' do
+      expect { |b|
+        _yield_with_args(1.1, "food", &b)
+      }.to yield_with_args(a_value_within(0.2).of(1), a_string_matching(/foo/))
+    end
+
+    it 'provides a description' do
+      description = yield_with_args(a_value_within(0.2).of(1), a_string_matching(/foo/)).description
+      expect(description).to eq("yield with args(a value within 0.2 of 1, a string matching /foo/)")
+    end
+
+    it 'fails with a useful error message when the matchers do not match the args' do
+      expect {
+        expect { |b|
+          _yield_with_args(2.1, "food", &b)
+        }.to yield_with_args(a_value_within(0.2).of(1), a_string_matching(/foo/))
+      }.to fail_with(dedent <<-EOS)
+        |expected given block to yield with arguments, but yielded with unexpected arguments
+        |expected: [(a value within 0.2 of 1), (a string matching /foo/)]
+        |     got: [2.1, "food"]
+      EOS
+    end
+  end
+
+  describe "expect {...}.not_to yield_with_args(3, 17)" do
+    it 'passes if the block yields with different arguments' do
+      expect { |b| _yield_with_args("a", "b", &b) }.not_to yield_with_args("a", "c")
+    end
+
+    it 'fails if the block yields with the given arguments' do
+      expect {
+        expect { |b| _yield_with_args("a", "b", &b) }.not_to yield_with_args("a", "b")
+      }.to fail_with(/expected given block not to yield with arguments, but yielded with expected arguments/)
+    end
+  end
+
+  describe "expect {...}.not_to yield_with_args(matcher, matcher)" do
+    it 'passes when the matchers do not match the args' do
+      expect { |b|
+        _yield_with_args(2.1, "food", &b)
+      }.not_to yield_with_args(a_value_within(0.2).of(1), a_string_matching(/foo/))
+    end
+
+    it 'fails with a useful error message when the matchers do not match the args' do
+      expect {
+        expect { |b|
+          _yield_with_args(1.1, "food", &b)
+        }.not_to yield_with_args(a_value_within(0.2).of(1), a_string_matching(/foo/))
+      }.to fail_with(dedent <<-EOS)
+        |expected given block not to yield with arguments, but yielded with expected arguments
+        |expected not: [(a value within 0.2 of 1), (a string matching /foo/)]
+        |         got: [1.1, "food"]
+      EOS
+    end
+  end
+
+  describe "expect {...}.to yield_with_args( false )" do
+    it 'passes if the block yields with the given arguments' do
+      expect { |b| _yield_with_args(false, &b) }.to yield_with_args(false)
+    end
+
+    it 'passes if the block yields with the given arguments using instance_exec' do
+      expect { |b| InstanceEvaler.new.yield_with_args(false, &b) }.to yield_with_args(false)
+    end
+
+    it 'fails if the block does not yield' do
+      expect {
+        expect { |b| _dont_yield(&b) }.to yield_with_args(false)
+      }.to fail_with(/expected given block to yield with arguments, but did not yield/)
+    end
+
+    it 'fails if the block yields with no arguments' do
+      expect {
+        expect { |b| _yield_with_no_args(&b) }.to yield_with_args(false)
+      }.to fail_with(/expected given block to yield with arguments, but yielded with unexpected arguments/)
+    end
+
+    it 'fails if the block yields with different arguments' do
+      expect {
+        expect { |b| _yield_with_args(false, &b) }.to yield_with_args(true)
+      }.to fail_with(/expected given block to yield with arguments, but yielded with unexpected arguments/)
+    end
+  end
+
+  describe "expect {...}.to yield_with_args(/reg/, /ex/)" do
+    it "passes if the block yields strings matching the regexes" do
+      expect { |b| _yield_with_args("regular", "expression", &b) }.to yield_with_args(/reg/, /ex/)
+    end
+
+    it "fails if the block yields strings that do not match the regexes" do
+      expect {
+        expect { |b| _yield_with_args("no", "match", &b) }.to yield_with_args(/reg/, /ex/)
+      }.to fail_with(/expected given block to yield with arguments, but yielded with unexpected arguments/)
+    end
+  end
+
+  describe "expect {...}.to yield_with_args(String, Fixnum)" do
+    it "passes if the block yields objects of the given classes" do
+      expect { |b| _yield_with_args("string", 15, &b) }.to yield_with_args(String, Fixnum)
+    end
+
+    it "passes if the block yields the given classes" do
+      expect { |b| _yield_with_args(String, Fixnum, &b) }.to yield_with_args(String, Fixnum)
+    end
+
+    it "fails if the block yields objects of different classes" do
+      expect {
+        expect { |b| _yield_with_args(15, "string", &b) }.to yield_with_args(String, Fixnum)
+      }.to fail_with(/expected given block to yield with arguments, but yielded with unexpected arguments/)
+    end
+  end
+end
+
+RSpec.describe "yield_successive_args matcher" do
+  include YieldHelpers
+  extend  YieldHelpers
+
+  it_behaves_like "an RSpec matcher",
+      :valid_value => lambda { |b| [1, 2].each(&b) },
+      :invalid_value => lambda { |b| _dont_yield(&b) } do
+    let(:matcher) { yield_successive_args(1, 2) }
+  end
+
+  it 'has a description' do
+    expect(yield_successive_args(1, 3).description).to eq("yield successive args(1, 3)")
+    expect(yield_successive_args([:a, 1], [:b, 2]).description).to eq("yield successive args([:a, 1], [:b, 2])")
+  end
+
+  it 'does not return a meaningful value from the block' do
+    val = nil
+    expect { |b| val = _yield_with_args(1, &b) }.to yield_successive_args(1)
+    expect(val).to be_nil
+  end
+
+  describe "expect {...}.to yield_successive_args([:a, 1], [:b, 2])" do
+    it 'passes when the block successively yields the given args' do
+      expect { |b| [ [:a, 1], [:b, 2] ].each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
+    end
+
+    it 'fails when the block does not yield that many times' do
+      expect {
+        expect { |b| [[:a, 1]].each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
+      }.to fail_with(/but yielded with unexpected arguments/)
+    end
+
+    it 'fails when the block yields the right number of times but with different arguments' do
+      expect {
+        expect { |b| [ [:a, 1], [:b, 3] ].each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
+      }.to fail_with(/but yielded with unexpected arguments/)
+    end
+  end
+
+  describe "expect {...}.to yield_successive_args(1, 2, 3)" do
+    it 'passes when the block successively yields the given args' do
+      expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
+    end
+
+    it 'passes when the block successively yields the given args using instance_exec' do
+      expect { |b| InstanceEvaler.new.each_arg(1, 2, 3, &b) }.to yield_successive_args(1, 2, 3)
+    end
+
+    it 'fails when the block does not yield the expected args' do
+      expect {
+        expect { |b| [1, 2, 4].each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
+      }.to fail_with(/but yielded with unexpected arguments/)
+    end
+  end
+
+  describe "expect {...}.to yield_successive_args(matcher, matcher)" do
+    it 'passes when the successively yielded args match the matchers' do
+      expect { |b|
+        %w[ food barn ].each(&b)
+      }.to yield_successive_args(a_string_matching(/foo/), a_string_matching(/bar/))
+    end
+
+    it 'fails when the successively yielded args do not match the matchers' do
+      expect {
+        expect { |b|
+          %w[ barn food ].each(&b)
+        }.to yield_successive_args(a_string_matching(/foo/), a_string_matching(/bar/))
+      }.to fail_with(dedent <<-EOS)
+        |expected given block to yield successively with arguments, but yielded with unexpected arguments
+        |expected: [(a string matching /foo/), (a string matching /bar/)]
+        |     got: ["barn", "food"]
+      EOS
+    end
+
+    it 'provides a description' do
+      description = yield_successive_args(a_string_matching(/foo/), a_string_matching(/bar/)).description
+      expect(description).to eq("yield successive args(a string matching /foo/, a string matching /bar/)")
+    end
+  end
+
+  describe "expect {...}.not_to yield_successive_args(1, 2, 3)" do
+    it 'passes when the block does not yield' do
+      expect { |b| _dont_yield(&b) }.not_to yield_successive_args(1, 2, 3)
+    end
+
+    it 'passes when the block yields the wrong number of times' do
+      expect { |b| [1, 2].each(&b) }.not_to yield_successive_args(1, 2, 3)
+    end
+
+    it 'passes when the block yields the wrong arguments' do
+      expect { |b| [1, 2, 4].each(&b) }.not_to yield_successive_args(1, 2, 3)
+    end
+
+    it 'fails when the block yields the given arguments' do
+      expect {
+        expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2, 3)
+      }.to fail_with(/expected given block not to yield successively/)
+    end
+
+    it 'fails if the expect block does not accept an argument', :if => (RUBY_VERSION.to_f > 1.8) do
+      expect {
+        expect { }.not_to yield_successive_args(1, 2, 3)
+      }.to raise_error(/expect block must accept an argument/)
+    end
+
+    it 'raises an error if the expect block arg is not passed to a method as a block' do
+      expect {
+        expect { |b| }.not_to yield_successive_args(1, 2, 3)
+      }.to raise_error(/must pass the argument.*as a block/)
+    end
+  end
+
+  describe "expect {...}.not_to yield_successive_args(matcher, matcher)" do
+    it 'passes when the successively yielded args match the matchers' do
+      expect { |b|
+        %w[ barn food ].each(&b)
+      }.not_to yield_successive_args(a_string_matching(/foo/), a_string_matching(/bar/))
+    end
+
+    it 'fails when the successively yielded args do not match the matchers' do
+      expect {
+        expect { |b|
+          %w[ food barn ].each(&b)
+        }.not_to yield_successive_args(a_string_matching(/foo/), a_string_matching(/bar/))
+      }.to fail_with(dedent <<-EOS)
+        |expected given block not to yield successively with arguments, but yielded with expected arguments
+        |expected not: [(a string matching /foo/), (a string matching /bar/)]
+        |         got: ["food", "barn"]
+      EOS
+    end
+  end
+
+  describe "expect {...}.to yield_successive_args(String, Fixnum)" do
+    it "passes if the block successively yields objects of the given classes" do
+      expect { |b| ["string", 15].each(&b) }.to yield_successive_args(String, Fixnum)
+    end
+
+    it "passes if the block yields the given classes" do
+      expect { |b| [String, Fixnum].each(&b) }.to yield_successive_args(String, Fixnum)
+    end
+
+    it "fails if the block yields objects of different classes" do
+      expect {
+        expect { |b| [15, "string"].each(&b) }.to yield_successive_args(String, Fixnum)
+      }.to fail_with(/expected given block to yield successively with arguments/)
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers/composable_spec.rb b/rspec-expectations/spec/rspec/matchers/composable_spec.rb
new file mode 100644
index 0000000..d88c150
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/composable_spec.rb
@@ -0,0 +1,77 @@
+module RSpec
+  module Matchers
+    RSpec.describe Composable do
+      RSpec::Matchers.define :matcher_using_surface_descriptions_in do |expected|
+        match { false }
+        failure_message { surface_descriptions_in(expected) }
+      end
+
+      it "does not blow up when surfacing descriptions from an unreadable IO object" do
+        expect {
+          expect(3).to matcher_using_surface_descriptions_in(STDOUT)
+        }.to fail_with(STDOUT.inspect)
+      end
+
+      it "doesn't mangle struct descriptions" do
+        model = Struct.new(:a).new(1)
+        expect {
+          expect(1).to matcher_using_surface_descriptions_in(model)
+        }.to fail_with(model.inspect)
+      end
+
+      RSpec::Matchers.define :all_but_one do |matcher|
+        match do |actual|
+          match_count = actual.count { |v| values_match?(matcher, v) }
+          actual.size == match_count + 1
+        end
+      end
+
+      context "when using a matcher instance that memoizes state multiple times in a composed expression" do
+        it "works properly in spite of the memoization" do
+          expect(["foo", "bar", "a"]).to all_but_one(have_string_length(3))
+        end
+
+        context "when passing a compound expression" do
+          it "works properly in spite of the memoization" do
+            expect(["A", "AB", "ABC"]).to all_but_one(
+                have_string_length(1).or have_string_length(2)
+            )
+          end
+        end
+      end
+
+      describe "cloning data structures containing matchers" do
+        include Composable
+
+        it "clones only the contained matchers" do
+          matcher_1   = eq(1)
+          matcher_2   = eq(2)
+          object      = Object.new
+          uncloneable = nil
+
+          data_structure = {
+            "foo"  => matcher_1,
+            "bar"  => [matcher_2, uncloneable],
+            "bazz" => object
+          }
+
+          cloned = with_matchers_cloned(data_structure)
+          expect(cloned).not_to equal(data_structure)
+
+          expect(cloned["foo"]).to be_a_clone_of(matcher_1)
+          expect(cloned["bar"].first).to be_a_clone_of(matcher_2)
+          expect(cloned["bazz"]).to equal(object)
+        end
+
+        it "copies custom matchers properly so they can work even though they have singleton behavior" do
+          expect("foo").to with_matchers_cloned(have_string_length 3)
+        end
+
+        it 'does not blow up when passed an array containing an IO object' do
+          stdout = STDOUT
+          expect(with_matchers_cloned([stdout]).first).to equal(stdout)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/define_negated_matcher_spec.rb b/rspec-expectations/spec/rspec/matchers/define_negated_matcher_spec.rb
new file mode 100644
index 0000000..b6f0e0a
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/define_negated_matcher_spec.rb
@@ -0,0 +1,199 @@
+module RSpec
+  module Matchers
+    RSpec.describe 'RSpec::Matchers.define_negated_matcher' do
+      RSpec::Matchers.define :my_base_non_negated_matcher do
+        match { |actual| actual == foo }
+
+        def foo
+          13
+        end
+
+        def description
+          "my base matcher description"
+        end
+      end
+
+      shared_examples "making a copy" do |copy_method|
+        context "when making a copy via `#{copy_method}`" do
+          it "uses a copy of the base matcher" do
+            base_matcher = include(3)
+            aliased = AliasedNegatedMatcher.new(base_matcher, Proc.new {})
+            copy = aliased.__send__(copy_method)
+
+            expect(copy).not_to equal(aliased)
+            expect(copy.base_matcher).not_to equal(base_matcher)
+            expect(copy.base_matcher).to be_a(RSpec::Matchers::BuiltIn::Include)
+            expect(copy.base_matcher.expected).to eq([3])
+          end
+
+          it "copies custom matchers properly so they can work even though they have singleton behavior" do
+            base_matcher = my_base_non_negated_matcher
+            aliased = AliasedNegatedMatcher.new(base_matcher, Proc.new { |a| a })
+            copy = aliased.__send__(copy_method)
+
+            expect(copy).not_to equal(aliased)
+            expect(copy.base_matcher).not_to equal(base_matcher)
+
+            expect(15).to copy
+
+            expect { expect(13).to copy }.to fail_with(/expected 13/)
+          end
+        end
+      end
+
+      include_examples "making a copy", :dup
+      include_examples "making a copy", :clone
+
+      RSpec::Matchers.define_negated_matcher :an_array_excluding, :include
+      it_behaves_like "an RSpec matcher", :valid_value => [1, 3], :invalid_value => [1, 2] do
+        let(:matcher) { an_array_excluding(2) }
+      end
+
+      it 'works properly when composed' do
+        list = 1.upto(10).to_a
+        expect { list.delete(5) }.to change { list }.to(an_array_excluding 5)
+      end
+
+      describe "the failure message" do
+        context "for a matcher with default failure messages" do
+          RSpec::Matchers.define(:be_awesome) { match(&:awesome?) }
+          RSpec::Matchers.define_negated_matcher :be_lame, :be_awesome
+
+          context "when failing positively" do
+            it "uses the phrasing from the provided defined matcher alias" do
+              expect {
+                expect(double(:awesome? => true, :inspect => "<Object>")).to be_lame
+              }.to fail_with("expected <Object> to be lame")
+            end
+          end
+
+          context "when failing negatively" do
+            it "uses the phrasing from the provided defined matcher alias" do
+              expect {
+                expect(double(:awesome? => false, :inspect => "<Object>")).not_to be_lame
+              }.to fail_with("expected <Object> not to be lame")
+            end
+          end
+
+          context "when accessed via an alias that is not included in failure messages" do
+            alias_method :be_fantastic, :be_awesome
+            RSpec::Matchers.define_negated_matcher :be_terrible, :be_fantastic
+
+            context "when failing positively" do
+              it "uses the wrapped matcher's `failure_message_when_negated`" do
+                expect {
+                  expect(double(:awesome? => true, :inspect => "<Object>")).to be_terrible
+                }.to fail_with("expected <Object> not to be awesome")
+              end
+            end
+
+            context "when failing negatively" do
+              it "uses the wrapped matcher's `failure_message`" do
+                expect {
+                  expect(double(:awesome? => false, :inspect => "<Object>")).not_to be_terrible
+                }.to fail_with("expected <Object> to be awesome")
+              end
+            end
+          end
+        end
+
+        context "for a matcher with a customized `failure_message_when_negated`" do
+          RSpec::Matchers.define(:be_tall) do
+            match(&:tall?)
+            failure_message_when_negated do |actual|
+              "expected #{actual.inspect} not to be tall, but was tall"
+            end
+          end
+          RSpec::Matchers.define_negated_matcher :be_short, :be_tall
+
+          context "when failing positively" do
+            it "uses the wrapped matcher's `failure_message_when_negated` since it may include more detail" do
+              expect {
+                expect(double(:tall? => true, :inspect => "<Object>")).to be_short
+              }.to fail_with("expected <Object> not to be tall, but was tall")
+            end
+          end
+
+          context "when failing negatively" do
+            it "uses the wrapped matcher's `failure_message` since it may include more detail" do
+              expect {
+                expect(double(:tall? => false, :inspect => "<Object>")).not_to be_short
+              }.to fail_with("expected <Object> to be tall")
+            end
+          end
+        end
+      end
+
+      context 'when no block is passed' do
+        RSpec::Matchers.define :be_an_odd_number do
+          match { |actual| actual.odd? }
+        end
+        RSpec::Matchers.define_negated_matcher :be_an_even_number, :be_an_odd_number
+
+        it 'uses the default negated description' do
+          expect(be_an_even_number.description).to eq("be an even number")
+        end
+
+        context "when matched positively" do
+          it 'matches values that fail the original matcher' do
+            expect { expect(22).to be_an_odd_number }.to fail_with("expected 22 to be an odd number")
+            expect(22).to be_an_even_number
+          end
+
+          it "fails matches against values that pass the original matcher" do
+            expect(21).to be_an_odd_number
+            expect { expect(21).to be_an_even_number }.to fail_with("expected 21 to be an even number")
+          end
+        end
+
+        context "when matched negatively" do
+          it 'matches values that fail the original matcher' do
+            expect { expect(21).not_to be_an_odd_number }.to fail_with("expected 21 not to be an odd number")
+            expect(21).not_to be_an_even_number
+          end
+
+          it "fails matches against values that pass the original matcher" do
+            expect(22).not_to be_an_odd_number
+            expect { expect(22).not_to be_an_even_number }.to fail_with("expected 22 not to be an even number")
+          end
+        end
+      end
+
+      context 'when the negated description is overriden' do
+        RSpec::Matchers.define :be_bigger_than_ten do
+          match { |actual| actual > 10 }
+        end
+        RSpec::Matchers.define_negated_matcher :be_smaller_than_ten, :be_bigger_than_ten do |desc|
+          "#{desc.sub('bigger', 'smaller')} (overriden)"
+        end
+
+        it 'overrides the description with the provided block' do
+          expect(be_smaller_than_ten.description).to eq("be smaller than ten (overriden)")
+        end
+
+        it 'overrides the failure message with the provided block' do
+          expect { expect(12).to be_smaller_than_ten }.to fail_with("expected 12 to be smaller than ten (overriden)")
+        end
+      end
+
+      context "for a matcher that has custom `match_when_negated` logic" do
+        RSpec::Matchers.define :matcher_with_custom_negation do |match_value|
+          match { match_value }
+          match_when_negated { |actual| actual == :does_not_match_true }
+        end
+        RSpec::Matchers.define_negated_matcher :negated_matcher_with_custom_negation, :matcher_with_custom_negation
+
+        it "uses the `match_when_negated` logic for matching" do
+          expect(:does_not_match_true).to negated_matcher_with_custom_negation(true)
+          expect {
+            expect(:does_not_match_false).to negated_matcher_with_custom_negation(true)
+          }.to fail
+        end
+
+        it "uses the `match` logic for `expect(..).not_to`" do
+          expect(:foo).not_to negated_matcher_with_custom_negation(true)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/description_generation_spec.rb b/rspec-expectations/spec/rspec/matchers/description_generation_spec.rb
new file mode 100644
index 0000000..8573d51
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/description_generation_spec.rb
@@ -0,0 +1,202 @@
+RSpec.describe "Matchers should be able to generate their own descriptions" do
+  after(:example) do
+    RSpec::Matchers.clear_generated_description
+  end
+
+  example "expect(...).to eq expected" do
+    expect("this").to eq "this"
+    expect(RSpec::Matchers.generated_description).to eq "should eq \"this\""
+  end
+
+  example "expect(...).to not eq expected" do
+    expect("this").not_to eq "that"
+    expect(RSpec::Matchers.generated_description).to eq "should not eq \"that\""
+  end
+
+  example "expect(...).to be empty (arbitrary predicate)" do
+    expect([]).to be_empty
+    expect(RSpec::Matchers.generated_description).to eq "should be empty"
+  end
+
+  example "expect(...).to not be empty (arbitrary predicate)" do
+    expect([1]).not_to be_empty
+    expect(RSpec::Matchers.generated_description).to eq "should not be empty"
+  end
+
+  example "expect(...).to be truthy" do
+    expect(true).to be_truthy
+    expect(RSpec::Matchers.generated_description).to eq "should be truthy"
+  end
+
+  example "expect(...).to be falsey" do
+    expect(false).to be_falsey
+    expect(RSpec::Matchers.generated_description).to eq "should be falsey"
+  end
+
+  example "expect(...).to be nil" do
+    expect(nil).to be_nil
+    expect(RSpec::Matchers.generated_description).to eq "should be nil"
+  end
+
+  example "expect(...).to be > n" do
+    expect(5).to be > 3
+    expect(RSpec::Matchers.generated_description).to eq "should be > 3"
+  end
+
+  example "expect(...).to be between min and max" do
+    expect(10).to be_between(0, 10)
+    expect(RSpec::Matchers.generated_description).to eq "should be between 0 and 10 (inclusive)"
+  end
+
+  example "expect(...).to be exclusively between min and max" do
+    expect(9).to be_between(0, 10).exclusive
+    expect(RSpec::Matchers.generated_description).to eq "should be between 0 and 10 (exclusive)"
+  end
+
+  example "expect(...).to be predicate arg1, arg2 and arg3" do
+    class Parent; end
+    class Child < Parent
+      def child_of?(*parents)
+        parents.all? { |parent| self.is_a?(parent) }
+      end
+    end
+    expect(Child.new).to be_a_child_of(Parent, Object)
+    expect(RSpec::Matchers.generated_description).to eq "should be a child of Parent and Object"
+  end
+
+  example "expect(...).to equal" do
+    expected = "expected"
+    expect(expected).to equal(expected)
+    expect(RSpec::Matchers.generated_description).to eq "should equal \"expected\""
+  end
+
+  example "expect(...).not_to equal" do
+    expect(5).not_to equal(37)
+    expect(RSpec::Matchers.generated_description).to eq "should not equal 37"
+  end
+
+  example "expect(...).to eql" do
+    expect("string").to eql("string")
+    expect(RSpec::Matchers.generated_description).to eq "should eql \"string\""
+  end
+
+  example "expect(...).not_to eql" do
+    expect("a").not_to eql(:a)
+    expect(RSpec::Matchers.generated_description).to eq "should not eql :a"
+  end
+
+  example "expect(...).to have_key" do
+    expect({:a => "a"}).to have_key(:a)
+    expect(RSpec::Matchers.generated_description).to eq "should have key :a"
+  end
+
+  example "expect(...).to have_some_method" do
+    object = Object.new
+    def object.has_eyes_closed?; true; end
+
+    expect(object).to have_eyes_closed
+    expect(RSpec::Matchers.generated_description).to eq 'should have eyes closed'
+  end
+
+  example "expect(...).to have_some_method(args*)" do
+    object = Object.new
+    def object.has_taste_for?(*args); true; end
+
+    expect(object).to have_taste_for("wine", "cheese")
+    expect(RSpec::Matchers.generated_description).to eq 'should have taste for "wine", "cheese"'
+  end
+
+  example "expect(...).to include(x)" do
+    expect([1,2,3]).to include(3)
+    expect(RSpec::Matchers.generated_description).to eq "should include 3"
+  end
+
+  example "expect(...).to include(x) when x responds to description but is not a matcher" do
+    obj = double(:description => "description", :inspect => "inspect")
+    expect([obj]).to include(obj)
+    expect(RSpec::Matchers.generated_description).to eq "should include inspect"
+  end
+
+  example "expect(...).to include(x) when x responds to description and is a matcher" do
+    matcher = double(:description                => "description",
+                     :matches?                   => true,
+                     :failure_message => "")
+    expect([matcher]).to include(matcher)
+    expect(RSpec::Matchers.generated_description).to eq "should include (description)"
+  end
+
+  example "expect(array).to contain_exactly(1, 2, 3)" do
+    expect([1,2,3]).to contain_exactly(1, 2, 3)
+    expect(RSpec::Matchers.generated_description).to eq "should contain exactly 1, 2, and 3"
+  end
+
+  example "expect(...).to match" do
+    expect("this string").to match(/this string/)
+    expect(RSpec::Matchers.generated_description).to eq "should match /this string/"
+  end
+
+  example "expect(...).to raise_error" do
+    expect { raise }.to raise_error
+    expect(RSpec::Matchers.generated_description).to eq "should raise Exception"
+  end
+
+  example "expect(...).to raise_error with class" do
+    expect { raise }.to raise_error(RuntimeError)
+    expect(RSpec::Matchers.generated_description).to eq "should raise RuntimeError"
+  end
+
+  example "expect(...).to raise_error with class and message" do
+    expect { raise "there was an error" }.to raise_error(RuntimeError, "there was an error")
+    expect(RSpec::Matchers.generated_description).to eq "should raise RuntimeError with \"there was an error\""
+  end
+
+  example "expect(...).to respond_to" do
+    expect([]).to respond_to(:insert)
+    expect(RSpec::Matchers.generated_description).to eq "should respond to #insert"
+  end
+
+  example "expect(...).to throw symbol" do
+    expect { throw :what_a_mess }.to throw_symbol
+    expect(RSpec::Matchers.generated_description).to eq "should throw a Symbol"
+  end
+
+  example "expect(...).to throw symbol (with named symbol)" do
+    expect { throw :what_a_mess }.to throw_symbol(:what_a_mess)
+    expect(RSpec::Matchers.generated_description).to eq "should throw :what_a_mess"
+  end
+
+  example "expect(...).to matcher_that_delegates_to_an_internal_expectation" do
+    expect(1).to matcher_that_delegates_to_an_internal_expectation
+    expect(RSpec::Matchers.generated_description).to eq "should matcher that delegates to an internal expectation"
+  end
+
+  example "expect(...).not_to matcher_that_delegates_to_an_internal_expectation" do
+    expect(1).not_to matcher_that_delegates_to_an_internal_expectation
+    expect(RSpec::Matchers.generated_description).to eq "should not matcher that delegates to an internal expectation"
+  end
+
+  RSpec::Matchers.define :matcher_that_delegates_to_an_internal_expectation do
+    match { expect(1).to eq(1) }
+    match_when_negated { expect(1).to eq(1) }
+  end
+
+  def team
+    Class.new do
+      def players
+        [1,2,3]
+      end
+    end.new
+  end
+end
+
+RSpec.describe "a Matcher with no description" do
+  it "provides a helpful message when used in a string-less example block" do
+    matcher = Class.new do
+      def matches?(ignore); true; end
+      def failure_message; ""; end
+    end.new
+
+    expect(5).to matcher
+    expect(RSpec::Matchers.generated_description).to match(/When you call.*description method/m)
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/dsl_spec.rb b/rspec-expectations/spec/rspec/matchers/dsl_spec.rb
new file mode 100644
index 0000000..ec3c4dd
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/dsl_spec.rb
@@ -0,0 +1,1102 @@
+# encoding: utf-8
+
+RSpec.describe "a matcher defined using the matcher DSL" do
+  def question?
+    :answer
+  end
+
+  def ok
+    "ok"
+  end
+
+  it "supports calling custom matchers from within other custom matchers" do
+    RSpec::Matchers.define :be_ok do
+      match { |actual_value| actual_value == ok }
+    end
+
+    RSpec::Matchers.define :be_well do
+      match { |actual_value| expect(actual_value).to be_ok }
+    end
+
+    expect(ok).to be_well
+  end
+
+  it "has access to methods available in the scope of the example" do
+    RSpec::Matchers::define(:matcher_a) {}
+    expect(matcher_a.question?).to eq(:answer)
+  end
+
+  it "raises when method is missing from local scope as well as matcher" do
+    RSpec::Matchers::define(:matcher_b) {}
+    expect { matcher_b.i_dont_exist }.to raise_error(NameError)
+  end
+
+  it "clears user instance variables between invocations" do
+    RSpec::Matchers::define(:be_just_like) do |expected|
+      match do |actual_value|
+        @foo ||= expected
+        @foo == actual_value
+      end
+    end
+
+    expect(3).to be_just_like(3)
+    expect(4).to be_just_like(4)
+  end
+
+
+  describe '#block_arg' do
+    before(:context) do
+      RSpec::Matchers.define :be_lazily_equal_to do
+        match { actual == block_arg.call }
+
+        description do
+          "be lazily equal to #{block_arg.call}"
+        end
+      end
+    end
+
+    it "it is used in a passing condition" do
+      expect(1).to be_lazily_equal_to { 1 }
+    end
+
+    it "it is used in a failing condition" do
+      expect { expect(1).to be_lazily_equal_to { 2 } }.to fail_with(/be lazily equal to 2/)
+    end
+  end
+
+  it "warns when passing block to the block of define", :if => (RUBY_VERSION.to_f > 1.8) do
+    expect(RSpec).to receive(:warning).with(/be_warning.*a_block.*block_arg/)
+
+    RSpec::Matchers.define :be_warning do |&a_block|
+      match { a_block }
+    end
+  end
+
+  describe "#respond_to?" do
+    it "returns true for methods in example scope" do
+      RSpec::Matchers::define(:matcher_c) {}
+      expect(matcher_c).to respond_to(:question?)
+    end
+
+    it "returns false for methods not defined in matcher or example scope" do
+      RSpec::Matchers::define(:matcher_d) {}
+      expect(matcher_d).not_to respond_to(:i_dont_exist)
+    end
+  end
+end
+
+class UnexpectedError < StandardError; end
+module MatcherHelperModule
+  def self.included(base)
+    base.module_exec do
+      def included_method; end
+    end
+  end
+
+  def self.extended(base)
+    base.instance_exec do
+      def extended_method; end
+    end
+  end
+
+  def greeting
+    "Hello, World"
+  end
+end
+
+module RSpec::Matchers::DSL
+  RSpec.describe Matcher do
+    def new_matcher(name, *expected, &block)
+      RSpec::Matchers::DSL::Matcher.new(name, block, self, *expected)
+    end
+
+    it_behaves_like "an RSpec matcher", :valid_value => 1, :invalid_value => 2 do
+      let(:matcher) do
+        new_matcher(:equal_to_1) do
+          match { |v| v == 1 }
+        end
+      end
+    end
+
+    it "can be stored aside and used later" do
+      # Supports using rspec-expectation matchers as argument matchers in
+      # rspec-mocks.
+      RSpec::Matchers.define :example_matcher do |expected|
+        match do |actual|
+          actual == expected
+        end
+      end
+
+      m1 = example_matcher(1)
+      m2 = example_matcher(2)
+
+      expect(m1.matches?(1)).to be_truthy
+      expect(m2.matches?(2)).to be_truthy
+    end
+
+    context 'using deprecated APIs' do
+      before { allow_deprecation }
+
+      describe "failure_message_for_should" do
+        let(:matcher) do
+          new_matcher(:foo) do
+            match { false }
+            failure_message_for_should { "failed" }
+          end
+        end
+        line = __LINE__ - 3
+
+        it 'defines the failure message for a positive expectation' do
+          expect {
+            expect(nil).to matcher
+          }.to fail_with("failed")
+        end
+
+        it 'prints a deprecation warning' do
+          expect_deprecation_with_call_site(__FILE__, line, /failure_message_for_should/)
+          matcher
+        end
+      end
+
+      describe "failure_message_for_should_not" do
+        let(:matcher) do
+          new_matcher(:foo) do
+            match { true }
+            failure_message_for_should_not { "failed" }
+          end
+        end
+        line = __LINE__ - 3
+
+        it 'defines the failure message for a negative expectation' do
+          expect {
+            expect(nil).not_to matcher
+          }.to fail_with("failed")
+        end
+
+        it 'prints a deprecation warning' do
+          expect_deprecation_with_call_site(__FILE__, line, /failure_message_for_should_not/)
+          matcher
+        end
+      end
+
+      describe "match_for_should" do
+        let(:matcher) do
+          new_matcher(:foo) do
+            match_for_should { |arg| arg }
+          end
+        end
+        line = __LINE__ - 3
+
+        it 'defines the positive expectation match logic' do
+          expect(true).to matcher
+          expect { expect(false).to matcher }.to fail_with(/foo/)
+        end
+
+        it 'prints a deprecation warning' do
+          expect_deprecation_with_call_site(__FILE__, line, /match_for_should/)
+          matcher
+        end
+      end
+
+      describe "match_for_should_not" do
+        let(:matcher) do
+          new_matcher(:foo) do
+            match_for_should_not { |arg| !arg }
+          end
+        end
+        line = __LINE__ - 3
+
+        it 'defines the positive expectation match logic' do
+          expect(false).not_to matcher
+          expect { expect(true).not_to matcher }.to fail_with(/foo/)
+        end
+
+        it 'prints a deprecation warning' do
+          expect_deprecation_with_call_site(__FILE__, line, /match_for_should_not/)
+          matcher
+        end
+      end
+    end
+
+    context "with an included module" do
+      let(:matcher) do
+        new_matcher(:be_a_greeting) do
+          include MatcherHelperModule
+          match { |actual| actual == greeting }
+        end
+      end
+
+      it "has access to the module's methods" do
+        matcher.matches?("Hello, World")
+      end
+
+      it "runs the module's included hook" do
+        expect(matcher).to respond_to(:included_method)
+      end
+
+      it "does not run the module's extended hook" do
+        expect(matcher).not_to respond_to(:extended_method)
+      end
+
+      it 'allows multiple modules to be included at once' do
+        m = new_matcher(:multiple_modules) do
+          include Enumerable, Comparable
+        end
+        expect(m).to be_a(Enumerable)
+        expect(m).to be_a(Comparable)
+      end
+    end
+
+    context "without overrides" do
+      let(:matcher) do
+        new_matcher(:be_a_multiple_of, 3) do |multiple|
+          match do |actual|
+            actual % multiple == 0
+          end
+        end
+      end
+
+      it "provides a default description" do
+        expect(matcher.description).to eq "be a multiple of 3"
+      end
+
+      it "provides a default positive expectation failure message" do
+        expect { expect(8).to matcher }.to fail_with 'expected 8 to be a multiple of 3'
+      end
+
+      it "provides a default negative expectation failure message" do
+        expect { expect(9).to_not matcher }.to fail_with 'expected 9 not to be a multiple of 3'
+      end
+    end
+
+    context "without overrides with chained matchers" do
+      let(:matcher) do
+        new_matcher(:be_bigger_than, 5) do |five|
+          match do |to_match|
+            (to_match > five) && smaller_than_ceiling?(to_match) && divisible_by_divisor?(to_match)
+          end
+
+          match_when_negated do |to_match|
+            (to_match <= five) || greater_than_ceiling(to_match) && not_divisible_by_divisor?(to_match)
+          end
+
+          chain :and_smaller_than do |ceiling|
+            @ceiling = ceiling
+          end
+
+          chain :and_divisible_by do |divisor|
+            @divisor = divisor
+          end
+
+        private
+
+          def smaller_than_ceiling?(to_match)
+            to_match < @ceiling
+          end
+
+          def greater_than_ceiling(to_match)
+            to_match >= @ceiling
+          end
+
+          def divisible_by_divisor?(to_match)
+            @divisor % to_match == 0
+          end
+
+          def not_divisible_by_divisor?(to_match)
+            @divisor % to_match != 0
+          end
+        end
+      end
+
+      context "when the matchers are chained" do
+        include_context "isolate include_chain_clauses_in_custom_matcher_descriptions"
+
+        context "without include_chain_clauses_in_custom_matcher_descriptions configured" do
+          before { RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions = false }
+          let(:match) { matcher.and_smaller_than(10).and_divisible_by(3) }
+
+          it "provides a default description that does not include any of the chained matchers' descriptions" do
+            expect(match.description).to eq 'be bigger than 5'
+          end
+
+          it "provides a default positive expectation failure message that does not include any of the chained matchers' descriptions" do
+            expect { expect(8).to match }.to fail_with 'expected 8 to be bigger than 5'
+          end
+
+          it "provides a default negative expectation failure message that does not include the any of the chained matchers's descriptions" do
+            expect { expect(9).to_not match }.to fail_with 'expected 9 not to be bigger than 5'
+          end
+        end
+
+        context "with include_chain_clauses_in_custom_matcher_descriptions configured to be true" do
+          before do
+            expect(RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions?).to be true
+          end
+
+          it "provides a default description that includes the chained matchers' descriptions in they were used" do
+            expect(matcher.and_divisible_by(3).and_smaller_than(29).and_smaller_than(20).and_divisible_by(5).description).to \
+              eq 'be bigger than 5 and divisible by 3 and smaller than 29 and smaller than 20 and divisible by 5'
+          end
+
+          it "provides a default positive expectation failure message that includes the chained matchers' failures" do
+            expect { expect(30).to matcher.and_smaller_than(29).and_divisible_by(3) }.to \
+              fail_with 'expected 30 to be bigger than 5 and smaller than 29 and divisible by 3'
+          end
+
+          it "provides a default negative expectation failure message that includes the chained matchers' failures" do
+            expect { expect(21).to_not matcher.and_smaller_than(29).and_divisible_by(3) }.to \
+              fail_with 'expected 21 not to be bigger than 5 and smaller than 29 and divisible by 3'
+          end
+        end
+
+        it 'only decides if to include the chained clauses at the time description is invoked' do
+          matcher.and_divisible_by(3)
+
+          expect {
+            RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions = false
+          }.to change { matcher.description }.
+            from('be bigger than 5 and divisible by 3').
+            to('be bigger than 5')
+        end
+      end
+    end
+
+    context "with separate match logic for positive and negative expectations" do
+      let(:matcher) do
+        new_matcher(:to_be_composed_of, 7, 11) do |a, b|
+          match do |actual|
+            actual == a * b
+          end
+
+          match_when_negated do |actual|
+            actual == a + b
+          end
+        end
+      end
+
+      it "invokes the match block for #matches?" do
+        expect(matcher.matches?(77)).to be_truthy
+        expect(matcher.matches?(18)).to be_falsey
+      end
+
+      it "invokes the match_when_negated block for #does_not_match?" do
+        expect(matcher.does_not_match?(77)).to be_falsey
+        expect(matcher.does_not_match?(18)).to be_truthy
+      end
+
+      it "provides a default failure message for negative expectations" do
+        matcher.does_not_match?(77)
+        expect(matcher.failure_message_when_negated).to eq "expected 77 not to to be composed of 7 and 11"
+      end
+
+      it 'can access helper methods from `match_when_negated`' do
+        matcher = new_matcher(:be_foo) do
+          def foo
+            :foo
+          end
+
+          match_when_negated do |actual|
+            actual != foo
+          end
+        end
+
+        expect(matcher.does_not_match?(:bar)).to be true
+      end
+    end
+
+    it "allows helper methods to be defined with #define_method to have access to matcher parameters" do
+      matcher = new_matcher(:name, 3, 4) do |a, b|
+        define_method(:sum) { a + b }
+      end
+
+      expect(matcher.sum).to eq 7
+    end
+
+    it "is not diffable by default" do
+      matcher = new_matcher(:name) { }
+      expect(matcher).not_to be_diffable
+    end
+
+    it "is diffable when told to be" do
+      matcher = new_matcher(:name) { diffable }
+      expect(matcher).to be_diffable
+    end
+
+    it 'handles multiline string diffs' do
+      actual   = "LINE1\nline2\n"
+      expected = "line1\nline2\n"
+
+      matcher = new_matcher(:custom_match, expected) do
+        match { |act| act == expected }
+        diffable
+      end
+
+      diff = nil
+      begin
+        allow(RSpec::Matchers.configuration).to receive(:color?).and_return(false)
+        expect(actual).to matcher
+      rescue RSpec::Expectations::ExpectationNotMetError => e
+        diff = e.message.sub(/\A.*Diff:/m, "Diff:").gsub(/^\s*/,'')
+      end
+
+      expect(diff).to eq "Diff:\n@@ -1,3 +1,3 @@\n-line1\n+LINE1\nline2\n"
+    end
+
+    it 'does not confuse the diffability of different matchers' do
+      # Necessary to guard against a regression that involved
+      # using a class variable to store the diffable state,
+      # which had the side effect of causing all custom matchers
+      # to share that state
+      m1 = new_matcher(:m1) { diffable }
+      m2 = new_matcher(:m2) { }
+      m3 = new_matcher(:m3) { diffable }
+
+      expect(m1).to be_diffable
+      expect(m2).not_to be_diffable
+      expect(m3).to be_diffable
+    end
+
+    it "provides expected" do
+      matcher = new_matcher(:name, "expected string") { }
+      expect(matcher.expected).to eq 'expected string'
+    end
+
+    it "provides expected when there is more than one argument" do
+      matcher = new_matcher(:name, "expected string", "another arg") { }
+      expect(matcher.expected).to eq ['expected string', "another arg"]
+    end
+
+    it "provides expected_as_array which returns an array regardless of expected" do
+      matcher = new_matcher(:name, "expected string") { }
+      expect(matcher.expected_as_array).to eq ['expected string']
+      matcher = new_matcher(:name, "expected\nstring") { }
+      expect(matcher.expected_as_array).to eq ["expected\nstring"]
+      matcher = new_matcher(:name, "expected string", "another arg") { }
+      expect(matcher.expected_as_array).to eq ['expected string', "another arg"]
+    end
+
+    it "provides actual when `match` is used" do
+      matcher = new_matcher(:name, 'expected string') do
+        match {|actual|}
+      end
+
+      matcher.matches?('actual string')
+
+      expect(matcher.actual).to eq 'actual string'
+    end
+
+    it "provides actual when the `match` block accepts splat args" do
+      matcher = new_matcher(:actual) do
+        match { |*actual| actual == [5] }
+      end
+
+      expect(matcher.matches?(5)).to be true
+      expect(matcher.matches?(4)).to be false
+    end
+
+    it 'allows an early `return` to be used from a `match` block' do
+      matcher = new_matcher(:with_return, 5) do |expected|
+        match { |actual| return true if expected == actual }
+      end
+
+      expect(matcher.matches?(5)).to be true
+      expect(matcher.matches?(4)).to be_falsey
+    end
+
+    it 'provides actual when `match_unless_raises` is used' do
+      matcher = new_matcher(:name, 'expected string') do
+        match_unless_raises(SyntaxError) {|actual|}
+      end
+
+      matcher.matches?('actual string')
+
+      expect(matcher.actual).to eq 'actual string'
+    end
+
+    it 'allows an early `return` to be used from a `match_unless_raises` block' do
+      matcher = new_matcher(:with_return) do
+        match_unless_raises(ArgumentError) do |actual|
+          return actual if [true, false].include?(actual)
+          raise ArgumentError
+        end
+      end
+
+      expect(matcher.matches?(true)).to be true
+      # It should match even if it returns false, because no error was raised.
+      expect(matcher.matches?(false)).to be true
+      expect(matcher.matches?(4)).to be_falsey
+    end
+
+    it 'provides actual when `match_when_negated` is used' do
+      matcher = new_matcher(:name, 'expected string') do
+        match_when_negated {|actual|}
+      end
+
+      matcher.does_not_match?('actual string')
+
+      expect(matcher.actual).to eq 'actual string'
+    end
+
+    it 'allows an early `return` to be used from a `match_when_negated` block' do
+      matcher = new_matcher(:with_return, 5) do |expected|
+        match_when_negated { |actual| return true if expected != actual }
+      end
+
+      expect(matcher.does_not_match?(5)).to be_falsey
+      expect(matcher.does_not_match?(4)).to be true
+    end
+
+    context "wrapping another expectation (expect(...).to eq ...)" do
+      let(:matcher) do
+        new_matcher(:name, "value") do |expected|
+          match do |actual|
+            expect(actual).to eq expected
+          end
+        end
+      end
+
+      it "returns true if the wrapped expectation passes" do
+        expect(self.matcher.matches?('value')).to be_truthy
+      end
+
+      it "returns false if the wrapped expectation fails" do
+        expect(self.matcher.matches?('other value')).to be_falsey
+      end
+
+      it "can use the `include` matcher from a `match` block" do
+        RSpec::Matchers.define(:descend_from) do |mod|
+          match do |klass|
+            expect(klass.ancestors).to include(mod)
+          end
+        end
+
+        expect(Fixnum).to descend_from(Object)
+        expect(Fixnum).not_to descend_from(Array)
+
+        expect {
+          expect(Fixnum).to descend_from(Array)
+        }.to fail_with(/expected Fixnum to descend from Array/)
+
+        expect {
+          expect(Fixnum).not_to descend_from(Object)
+        }.to fail_with(/expected Fixnum not to descend from Object/)
+      end
+
+      it "can use the `match` matcher from a `match` block" do
+        RSpec::Matchers.define(:be_a_phone_number_string) do
+          match do |string|
+            expect(string).to match(/\A\d{3}\-\d{3}\-\d{4}\z/)
+          end
+        end
+
+        expect("206-123-1234").to be_a_phone_number_string
+        expect("foo").not_to be_a_phone_number_string
+
+        expect {
+          expect("foo").to be_a_phone_number_string
+        }.to fail_with(/expected "foo" to be a phone number string/)
+
+        expect {
+          expect("206-123-1234").not_to be_a_phone_number_string
+        }.to fail_with(/expected "206-123-1234" not to be a phone number string/)
+      end
+    end
+
+    context "with overrides" do
+      let(:matcher) do
+        new_matcher(:be_boolean, true) do |boolean|
+          match do |actual|
+            actual
+          end
+          description do |actual|
+            "be the boolean #{boolean} (actual was #{actual})"
+          end
+          failure_message do |actual|
+            "expected #{actual} to be the boolean #{boolean}"
+          end
+          failure_message_when_negated do |actual|
+            "expected #{actual} not to be the boolean #{boolean}"
+          end
+        end
+      end
+
+      it "does not hide result of match block when true" do
+        expect(self.matcher.matches?(true)).to be_truthy
+      end
+
+      it "does not hide result of match block when false" do
+        expect(self.matcher.matches?(false)).to be_falsey
+      end
+
+      it "overrides the description (which yields `actual`)" do
+        self.matcher.matches?(true)
+        expect(self.matcher.description).to eq "be the boolean true (actual was true)"
+      end
+
+      it "overrides the failure message for positive expectations" do
+        self.matcher.matches?(false)
+        expect(self.matcher.failure_message).to eq "expected false to be the boolean true"
+      end
+
+      it "overrides the failure message for negative expectations" do
+        self.matcher.matches?(true)
+        expect(self.matcher.failure_message_when_negated).to eq "expected true not to be the boolean true"
+      end
+
+      it 'can access helper methods from `description`' do
+        matcher = new_matcher(:desc) do
+          def subdesc() "sub description" end
+          description { "Desc (#{subdesc})" }
+        end
+
+        expect(matcher.description).to eq("Desc (sub description)")
+      end
+
+      it 'can access helper methods from `failure_message`' do
+        matcher = new_matcher(:positive_failure_message) do
+          def helper() "helper" end
+          failure_message { helper }
+        end
+
+        expect(matcher.failure_message).to eq("helper")
+      end
+
+      it 'can access helper methods from `failure_message_when_negated`' do
+        matcher = new_matcher(:negative_failure_message) do
+          def helper() "helper" end
+          failure_message_when_negated { helper }
+        end
+
+        expect(matcher.failure_message_when_negated).to eq("helper")
+      end
+
+      it 'can exit early with a `return` from `description` just like in a method' do
+        matcher = new_matcher(:desc) do
+          description { return "Desc" }
+        end
+
+        expect(matcher.description).to eq("Desc")
+      end
+
+      it 'can exit early with a `return` from `failure_message` just like in a method' do
+        matcher = new_matcher(:positive_failure_message) do
+          failure_message { return "msg" }
+        end
+
+        expect(matcher.failure_message).to eq("msg")
+      end
+
+      it 'can exit early with a `return` from `failure_message_when_negated` just like in a method' do
+        matcher = new_matcher(:negative_failure_message) do
+          failure_message_when_negated { return "msg" }
+        end
+
+        expect(matcher.failure_message_when_negated).to eq("msg")
+      end
+    end
+
+    context "with description override and chained matcher" do
+      context "by default" do
+        let(:matcher) do
+          new_matcher(:be_even) do
+            match do |to_match|
+              (to_match % 2 == 0) && (to_match % @divisible_by == 0)
+            end
+
+            chain :and_divisible_by do |divisible_by|
+              @divisible_by = divisible_by
+            end
+
+            description { super() + " and divisible by #{@divisible_by}" }
+          end
+        end
+
+        context "with include_chain_clauses_in_custom_matcher_descriptions configured to false" do
+          include_context "isolate include_chain_clauses_in_custom_matcher_descriptions"
+          before { RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions = false }
+
+          it "provides a default description that does not include any of the chained matchers' descriptions" do
+            expect(self.matcher.and_divisible_by(10).description).to eq 'be even and divisible by 10'
+          end
+        end
+
+        context "with include_chain_clauses_in_custom_matcher_descriptions configured to true" do
+          it "provides a default description that does includes the chained matchers' descriptions" do
+            expect(self.matcher.and_divisible_by(10).description).to eq 'be even and divisible by 10 and divisible by 10'
+          end
+        end
+      end
+    end
+
+    context "matching blocks" do
+      it 'cannot match blocks by default' do
+        matcher = new_matcher(:foo) { match { true } }
+        expect(3).to matcher
+
+        expect {
+          expect { 3 }.to matcher
+        }.to fail_with(/must pass an argument/)
+      end
+
+      it 'can match blocks if it declares `supports_block_expectations`' do
+        matcher = new_matcher(:foo) do
+          match { true }
+          supports_block_expectations
+        end
+
+        expect(3).to matcher
+        expect { 3 }.to matcher
+      end
+    end
+
+    context "#new" do
+      it "passes matches? arg to match block" do
+        matcher = new_matcher(:ignore) do
+          match do |actual|
+            actual == 5
+          end
+        end
+        expect(matcher.matches?(5)).to be_truthy
+      end
+
+      it "exposes arg submitted through #new to matcher block" do
+        matcher = new_matcher(:ignore, 4) do |expected|
+          match do |actual|
+            actual > expected
+          end
+        end
+        expect(matcher.matches?(5)).to be_truthy
+      end
+    end
+
+    context "with no args" do
+      let(:matcher) do
+        new_matcher(:matcher_name) do
+          match do |actual|
+            actual == 5
+          end
+        end
+      end
+
+      it "matches" do
+        expect(self.matcher.matches?(5)).to be_truthy
+      end
+
+      it "describes" do
+        expect(self.matcher.description).to eq "matcher name"
+      end
+    end
+
+    context "with 1 arg" do
+      let(:matcher) do
+        new_matcher(:matcher_name, 1) do |expected|
+          match do |actual|
+            actual == 5 && expected == 1
+          end
+        end
+      end
+
+      it "matches" do
+        expect(self.matcher.matches?(5)).to be_truthy
+      end
+
+      it "describes" do
+        expect(self.matcher.description).to eq "matcher name 1"
+      end
+    end
+
+    context "with multiple args" do
+      let(:matcher) do
+        new_matcher(:matcher_name, 1, 2, 3, 4) do |a, b, c, d|
+          match do |sum|
+            a + b + c + d == sum
+          end
+        end
+      end
+
+      it "matches" do
+        expect(self.matcher.matches?(10)).to be_truthy
+      end
+
+      it "describes" do
+        expect(self.matcher.description).to eq "matcher name 1, 2, 3, and 4"
+      end
+    end
+
+    it "supports helper methods" do
+      matcher = new_matcher(:be_similar_to, [1, 2, 3]) do |sample|
+        match do |actual|
+          similar?(sample, actual)
+        end
+
+        def similar?(a, b)
+          a.sort == b.sort
+        end
+      end
+
+      expect(matcher.matches?([2,3,1])).to be_truthy
+    end
+
+    it "supports fluent interface" do
+      matcher = new_matcher(:first_word) do
+        def second_word
+          self
+        end
+      end
+
+      expect(matcher.second_word).to eq matcher
+    end
+
+    it "treats method missing normally for undeclared methods" do
+      matcher = new_matcher(:ignore) { }
+      expect { matcher.non_existent_method }.to raise_error(NoMethodError)
+    end
+
+    it "has access to other matchers" do
+      matcher = new_matcher(:ignore, 3) do |expected|
+        match do |actual|
+          extend RSpec::Matchers
+          expect(actual).to eql(5 + expected)
+        end
+      end
+
+      expect(matcher.matches?(8)).to be_truthy
+    end
+
+    context 'when multiple instances of the same matcher are used in the same example' do
+      RSpec::Matchers.define(:be_like_a) do |expected|
+        match { |actual| actual == expected }
+        description { "be like a #{expected}" }
+        failure_message { "expected to be like a #{expected}" }
+        failure_message_when_negated { "expected not to be like a #{expected}" }
+      end
+
+      # Note: these bugs were only exposed when creating both instances
+      # first, then checking their descriptions/failure messages.
+      #
+      # That's why we eager-instantiate them here.
+      let!(:moose) { be_like_a("moose") }
+      let!(:horse) { be_like_a("horse") }
+
+      it 'allows them to use the expected value in the description' do
+        expect(horse.description).to eq("be like a horse")
+        expect(moose.description).to eq("be like a moose")
+      end
+
+      it 'allows them to use the expected value in the positive failure message' do
+        expect(moose.failure_message).to eq("expected to be like a moose")
+        expect(horse.failure_message).to eq("expected to be like a horse")
+      end
+
+      it 'allows them to use the expected value in the negative failure message' do
+        expect(moose.failure_message_when_negated).to eq("expected not to be like a moose")
+        expect(horse.failure_message_when_negated).to eq("expected not to be like a horse")
+      end
+
+      it 'allows them to match separately' do
+        expect("moose").to moose
+        expect("horse").to horse
+        expect("horse").not_to moose
+        expect("moose").not_to horse
+      end
+    end
+
+    describe "#match_unless_raises" do
+      context "with an assertion" do
+        mod = Module.new do
+          def assert_equal(a,b)
+            raise UnexpectedError.new("#{b} does not equal #{a}") unless a == b
+          end
+        end
+
+        let(:matcher) do
+          new_matcher(:equal, 4) do |expected|
+            include mod
+            match_unless_raises UnexpectedError do
+              assert_equal expected, self.actual
+            end
+          end
+        end
+
+        context "with passing assertion" do
+          it "passes" do
+            expect(self.matcher.matches?(4)).to be_truthy
+          end
+        end
+
+        context "with failing assertion" do
+          it "fails" do
+            expect(self.matcher.matches?(5)).to be_falsey
+          end
+
+          it "provides the raised exception" do
+            self.matcher.matches?(5)
+            expect(self.matcher.rescued_exception.message).to eq("5 does not equal 4")
+          end
+        end
+      end
+
+      context "with an unexpected error" do
+        it "raises the error" do
+          matcher = new_matcher(:foo, :bar) do |expected|
+            match_unless_raises SyntaxError do |actual|
+              raise "unexpected exception"
+            end
+          end
+
+          expect {
+            matcher.matches?(:bar)
+          }.to raise_error("unexpected exception")
+        end
+      end
+
+      context "without a specified error class" do
+        let(:matcher) do
+          new_matcher(:foo) do
+            match_unless_raises do |actual|
+              raise Exception unless actual == 5
+            end
+          end
+        end
+
+        it 'passes if no error is raised' do
+          expect(self.matcher.matches?(5)).to be true
+        end
+
+        it 'fails if an exception is raised' do
+          expect(self.matcher.matches?(4)).to be false
+        end
+      end
+
+    end
+
+    it "can define chainable methods" do
+      matcher = new_matcher(:name) do
+        chain(:expecting) do |expected_value|
+          @expected_value = expected_value
+        end
+        match { |actual| actual == @expected_value }
+      end
+
+      expect(matcher.expecting('value').matches?('value')).to be_truthy
+      expect(matcher.expecting('value').matches?('other value')).to be_falsey
+    end
+
+    it "can define chainable setters" do
+      matcher = new_matcher(:name) do
+        chain(:expecting, :expected_value)
+        match { |actual| actual == expected_value() }
+      end
+
+      expect(matcher.expecting('value').matches?('value')).to be_truthy
+      expect(matcher.expecting('value').matches?('other value')).to be_falsey
+    end
+
+    it "can define chainable setters for several attributes" do
+      matcher = new_matcher(:name) do
+        chain(:expecting, :expected_value, :min_value, :max_value)
+        match { |actual| actual == expected_value() && actual >= min_value && actual <= max_value }
+      end
+
+      expect(matcher.expecting('value', 'apple', 'zebra').matches?('value')).to be_truthy
+      expect(matcher.expecting('value', 'apple', 'zebra').matches?('other value')).to be_falsey
+      expect(matcher.expecting('other value', 'parrot', 'zebra').matches?('other value')).to be_falsey
+    end
+
+    it "raises when neither a `chain` block nor attribute name is provided" do
+      expect do
+        new_matcher(:name) do
+          chain(:expecting)
+        end
+      end.to raise_error(ArgumentError)
+    end
+
+    it "raises when both a `chain` block and attribute name are provided" do
+      expect do
+        new_matcher(:name) do
+          chain(:expecting, :expected_value) do |expected_value|
+            @expected_value = expected_value
+          end
+        end
+      end.to raise_error(ArgumentError)
+    end
+
+    it 'can use an early return from a `chain` block' do
+      matcher = new_matcher(:name) do
+        chain(:expecting) do |expected_value|
+          @expected_value = expected_value
+          return
+        end
+        match { |actual| actual == @expected_value }
+      end
+
+      expect(matcher.expecting('value').matches?('value')).to be_truthy
+      expect(matcher.expecting('value').matches?('other value')).to be_falsey
+    end
+
+    it 'allows chainable methods to accept blocks' do
+      matcher = new_matcher(:name) do
+        chain(:for_block) { |&b| @block = b }
+        match { |value| @block.call == value }
+      end
+
+      expect(matcher.for_block { 5 }.matches?(5)).to be true
+      expect(matcher.for_block { 3 }.matches?(4)).to be false
+    end
+
+    it "prevents name collisions on chainable methods from different matchers" do
+      m1 = new_matcher(:m1) { chain(:foo) { raise "foo in m1" } }
+      m2 = new_matcher(:m2) { chain(:foo) { raise "foo in m2" } }
+
+      expect { m1.foo }.to raise_error("foo in m1")
+      expect { m2.foo }.to raise_error("foo in m2")
+    end
+
+    context "defined using the dsl" do
+      def a_method_in_the_example
+        "method defined in the example"
+      end
+
+      it "can access methods in the running example" do |example|
+        RSpec::Matchers.define(:__access_running_example) do
+          match do |actual|
+            a_method_in_the_example == "method defined in the example"
+          end
+        end
+        expect(example).to __access_running_example
+      end
+
+      it 'can get a method object for methods in the running example', :if => (RUBY_VERSION.to_f > 1.8) do
+        matcher = new_matcher(:get_method_object) { }
+        method  = matcher.method(:a_method_in_the_example)
+        expect(method.call).to eq("method defined in the example")
+      end
+
+      it 'indicates that it responds to a method from the running example' do
+        matcher = new_matcher(:respond_to) { }
+        expect(matcher).to respond_to(:a_method_in_the_example)
+        expect(matcher).not_to respond_to(:a_method_not_in_the_example)
+      end
+
+      it "raises NoMethodError for methods not in the running_example" do |example|
+        RSpec::Matchers.define(:__raise_no_method_error) do
+          match do |actual|
+            self.a_method_not_in_the_example == "method defined in the example"
+          end
+        end
+
+        expected_msg = "RSpec::Matchers::DSL::Matcher"
+        expected_msg << " __raise_no_method_error" unless rbx?
+
+        expect {
+          expect(example).to __raise_no_method_error
+        }.to raise_error(NoMethodError, /#{expected_msg}/)
+      end
+
+      def rbx?
+        defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+      end
+    end
+
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/expecteds_for_multiple_diffs_spec.rb b/rspec-expectations/spec/rspec/matchers/expecteds_for_multiple_diffs_spec.rb
new file mode 100644
index 0000000..ec07daf
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/expecteds_for_multiple_diffs_spec.rb
@@ -0,0 +1,114 @@
+module RSpec
+  module Matchers
+    RSpec.describe ExpectedsForMultipleDiffs do
+
+      before do
+        stub_const("::RSpec::Matchers::ExpectedsForMultipleDiffs::DESCRIPTION_MAX_LENGTH", 30)
+      end
+
+      class FakeDiffer
+        def self.diff(actual, expected)
+          [actual, expected].inspect
+        end
+      end
+
+      let(:differ) { FakeDiffer }
+
+      let(:message) { "a message" }
+      let(:actual) { "actual value" }
+
+      let(:wrapped_value) { described_class.from("expected value") }
+
+      let(:matcher_1) { instance_double(BuiltIn::BaseMatcher, :description => "matcher 1 description", :expected => "expected 1") }
+      let(:matcher_2) { instance_double(BuiltIn::BaseMatcher, :description => "matcher 2 description", :expected => "expected 2") }
+      let(:matcher_3) { instance_double(BuiltIn::BaseMatcher, :description => "matcher 3 description", :expected => "expected 3") }
+
+      let(:long_description) { "a very very long description for my custom smart matcher, which can be used for everything" }
+      let(:truncated_description) { "a very very long descriptio..." }
+      let(:matcher_with_long_description) { instance_double(BuiltIn::BaseMatcher, :description => long_description, :expected => "expected value") }
+
+      let(:matcher_without_description_defined) { double("custom matcher", :expected => "expected value", :inspect => "#<CustomMatcher:0xf0c8561a55>") }
+
+      before { allow(matcher_without_description_defined).to receive(:description).and_raise(NoMethodError) }
+
+      describe ".from" do
+        it "wraps provided value in ExpectedsForMultipleDiffs" do
+          expect(wrapped_value).to be_a(described_class)
+        end
+
+        it "returns original value if it was already wrapped" do
+          expect(described_class.from(wrapped_value)).to be(wrapped_value)
+        end
+      end
+
+      describe ".for_many_matchers" do
+        let(:wrapped_value) { described_class.for_many_matchers([matcher_1, matcher_2, matcher_3]) }
+
+        it "has a diff for all matchers with their description" do
+          expect(wrapped_value.message_with_diff(
+            message, differ, actual
+          )).to eq(dedent <<-EOS)
+            |a message
+            |Diff for (matcher 1 description):["actual value", "expected 1"]
+            |Diff for (matcher 2 description):["actual value", "expected 2"]
+            |Diff for (matcher 3 description):["actual value", "expected 3"]
+          EOS
+        end
+      end
+
+      describe "#message_with_diff" do
+        it "returns just provided message if diff is empty" do
+          allow(FakeDiffer).to receive(:diff) { "" }
+          expect(wrapped_value.message_with_diff(
+            message, differ, actual
+          )).to eq(dedent <<-EOS)
+            |a message
+          EOS
+        end
+
+        it "returns regular message with diff when single expected" do
+          expect(wrapped_value.message_with_diff(
+            message, differ, actual
+          )).to eq(dedent <<-EOS)
+            |a message
+            |Diff:["actual value", "expected value"]
+          EOS
+        end
+
+        it "returns message with diff and matcher description when single expected with matcher" do
+          wrapped_value = described_class.for_many_matchers([include("expected value")])
+
+          expect(wrapped_value.message_with_diff(
+            message, differ, actual
+          )).to eq(dedent <<-EOS)
+            |a message
+            |Diff for (include "expected value"):["actual value", ["expected value"]]
+          EOS
+        end
+
+        it "returns message with diff and truncated matcher description if it is too long" do
+          wrapped_value = described_class.for_many_matchers([matcher_with_long_description])
+
+          expect(wrapped_value.message_with_diff(
+            message, differ, actual
+          )).to eq(dedent <<-EOS)
+            |a message
+            |Diff for (#{truncated_description}):["actual value", "expected value"]
+          EOS
+        end
+
+        it "handles custom matchers without description defined" do
+          wrapped_value = described_class.for_many_matchers([matcher_without_description_defined])
+
+          expect(wrapped_value.message_with_diff(
+            message, differ, actual
+          )).to eq(dedent <<-EOS)
+            |a message
+            |Diff for (#{matcher_without_description_defined.inspect}):["actual value", "expected value"]
+          EOS
+        end
+      end
+
+    end
+  end
+end
diff --git a/rspec-expectations/spec/rspec/matchers/legacy_spec.rb b/rspec-expectations/spec/rspec/matchers/legacy_spec.rb
new file mode 100644
index 0000000..47b2ef8
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers/legacy_spec.rb
@@ -0,0 +1,104 @@
+module RSpec
+  module Matchers
+    RSpec.describe "Legacy matchers" do
+      it 'still provides a `LegacyMacherAdapter` constant because 3.0 was released with ' +
+         'it and it would be a SemVer violation to remove it before 4.0' do
+        expect(Expectations::LegacyMacherAdapter).to be(Expectations::LegacyMatcherAdapter)
+      end
+
+      shared_examples "a matcher written against a legacy protocol" do |matcher_class|
+        matcher = matcher_class.new
+        before { allow_deprecation }
+
+        backwards_compat_matcher = Class.new(matcher_class) do
+          def failure_message; "failure when positive"; end
+          def failure_message_when_negated; "failure when negative"; end
+        end.new
+
+        it 'is still considered to be a matcher' do
+          expect(Matchers.is_a_matcher?(matcher)).to be true
+        end
+
+        context 'when matched positively' do
+          it 'returns the positive expectation failure message' do
+            expect {
+              expect(false).to matcher
+            }.to fail_with("failure when positive")
+          end
+
+          it 'warns about the deprecated protocol' do
+            expect_warn_deprecation_with_call_site(__FILE__, __LINE__ + 1, /legacy\s+RSpec\s+matcher/)
+            expect(true).to matcher
+          end
+
+          it 'does not warn when it also defines the current methods (i.e. to be compatible on multiple RSpec versions)' do
+            expect_no_deprecations
+
+            expect {
+              expect(false).to backwards_compat_matcher
+            }.to fail_with("failure when positive")
+          end
+        end
+
+        context 'when matched negatively' do
+          it 'returns the negative expectation failure message' do
+            expect {
+              expect(true).not_to matcher
+            }.to fail_with("failure when negative")
+          end
+
+          it 'warns about the deprecated protocol' do
+            expect_warn_deprecation_with_call_site(__FILE__, __LINE__ + 1, /legacy\s+RSpec\s+matcher/)
+            expect(false).not_to matcher
+          end
+
+          it 'does not warn when it also defines the current methods (i.e. to be compatible on multiple RSpec versions)' do
+            expect_no_deprecations
+
+            expect {
+              expect(true).not_to backwards_compat_matcher
+            }.to fail_with("failure when negative")
+          end
+
+          def pending_on_rbx
+            return unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+            pending "intermittently fails on RBX due to https://github.com/rubinius/rubinius/issues/2845"
+          end
+
+          it 'calls `does_not_match?` if it is defined on the matcher' do
+            pending_on_rbx
+
+            called = false
+            with_does_not_match = Class.new(matcher_class) do
+              define_method(:does_not_match?) { |actual| called = true; !actual }
+            end.new
+
+            expect(false).not_to with_does_not_match
+            expect(called).to be true
+          end
+        end
+      end
+
+      context "written using the RSpec 2.x `failure_message_for_should` and `failure_message_for_should_not` protocol" do
+        matcher_class = Class.new do
+          def matches?(actual); actual; end
+          def failure_message_for_should; "failure when positive"; end
+          def failure_message_for_should_not; "failure when negative"; end
+        end
+
+        it_behaves_like "a matcher written against a legacy protocol", matcher_class
+      end
+
+      context "written using the older `failure_message` and `negative_failure_message` protocol" do
+        matcher_class = Class.new do
+          def matches?(actual); actual; end
+          def failure_message; "failure when positive"; end
+          def negative_failure_message; "failure when negative"; end
+        end
+
+        it_behaves_like "a matcher written against a legacy protocol", matcher_class
+      end
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/rspec/matchers_spec.rb b/rspec-expectations/spec/rspec/matchers_spec.rb
new file mode 100644
index 0000000..8dcceb7
--- /dev/null
+++ b/rspec-expectations/spec/rspec/matchers_spec.rb
@@ -0,0 +1,108 @@
+main = self
+RSpec.describe RSpec::Matchers do
+  include ::RSpec::Support::InSubProcess
+
+  describe ".configuration" do
+    it 'returns a memoized configuration instance' do
+      expect(RSpec::Matchers.configuration).to be_a(RSpec::Expectations::Configuration)
+      expect(RSpec::Matchers.configuration).to be(RSpec::Matchers.configuration)
+    end
+  end
+
+  it 'can be mixed into `main`' do
+    in_sub_process do
+      main.instance_eval do
+        include RSpec::Matchers
+        expect(3).to eq(3)
+        expect(3).to be_odd
+
+        expect {
+          expect(4).to be_zero
+        }.to fail_with("expected `4.zero?` to return true, got false")
+      end
+    end
+  end
+end
+
+module RSpec
+  module Matchers
+    RSpec.describe ".is_a_matcher?" do
+      it 'does not match BasicObject', :if => RUBY_VERSION.to_f > 1.8 do
+        expect(RSpec::Matchers.is_a_matcher?(BasicObject.new)).to eq(false)
+      end
+
+      it 'is registered with RSpec::Support' do
+        expect(RSpec::Support.is_a_matcher?(be_even)).to eq(true)
+      end
+
+      it 'does not match a multi-element array' do
+        # our original implementation regsitered the matcher definition as
+        # `&RSpec::Matchers.method(:is_a_matcher?)`, which has a bug
+        # on 1.8.7:
+        #
+        # irb(main):001:0> def foo(x); end
+        # => nil
+        # irb(main):002:0> method(:foo).call([1, 2, 3])
+        # => nil
+        # irb(main):003:0> method(:foo).to_proc.call([1, 2, 3])
+        # ArgumentError: wrong number of arguments (3 for 1)
+        #   from (irb):1:in `foo'
+        #   from (irb):1:in `to_proc'
+        #   from (irb):3:in `call'
+        #
+        # This spec guards against a regression for that case.
+        expect(RSpec::Support.is_a_matcher?([1, 2, 3])).to eq(false)
+      end
+    end
+
+    RSpec.describe "built in matchers" do
+      let(:matchers) do
+        BuiltIn.constants.map { |n| BuiltIn.const_get(n) }.select do |m|
+          m.method_defined?(:matches?) && m.method_defined?(:failure_message)
+        end
+      end
+
+      specify "they all have defined #=== so they can be composable" do
+        missing_threequals = matchers.select do |m|
+          m.instance_method(:===).owner == ::Kernel
+        end
+
+        # This spec is merely to make sure we don't forget to make
+        # a built-in matcher implement `===`. It doesn't check the
+        # semantics of that. Use the "an RSpec matcher" shared
+        # example group to actually check the semantics.
+        expect(missing_threequals).to eq([])
+      end
+
+      specify "they all have defined #and and #or so they support compound expectations" do
+        noncompound_matchers = matchers.reject do |m|
+          m.method_defined?(:and) || m.method_defined?(:or)
+        end
+
+        expect(noncompound_matchers).to eq([])
+      end
+
+      shared_examples "a well-behaved method_missing hook" do
+        include MinitestIntegration
+
+        it "raises a NoMethodError (and not SystemStackError) for an undefined method" do
+          with_minitest_loaded do
+            expect { subject.some_undefined_method }.to raise_error(NoMethodError)
+          end
+        end
+      end
+
+      describe "RSpec::Matchers method_missing hook", :slow do
+        subject { self }
+
+        it_behaves_like "a well-behaved method_missing hook"
+
+        context 'when invoked in a Minitest::Test' do
+          subject { Minitest::Test.allocate }
+          it_behaves_like "a well-behaved method_missing hook"
+        end
+      end
+    end
+  end
+end
+
diff --git a/rspec-expectations/spec/spec_helper.rb b/rspec-expectations/spec/spec_helper.rb
new file mode 100644
index 0000000..1d93d05
--- /dev/null
+++ b/rspec-expectations/spec/spec_helper.rb
@@ -0,0 +1,94 @@
+require 'rspec/support/spec'
+
+RSpec::Support::Spec.setup_simplecov do
+  minimum_coverage 97
+end
+
+Dir['./spec/support/**/*'].each do |f|
+  require f.sub(%r{\./spec/}, '')
+end
+
+module FormattingSupport
+  def dedent(string)
+    string.gsub(/^\s+\|/, '').chomp
+  end
+end
+
+RSpec::configure do |config|
+  config.color = true
+  config.order = :random
+
+  config.include FormattingSupport
+
+  config.expect_with :rspec do |expectations|
+    $default_expectation_syntax = expectations.syntax
+    expectations.syntax = :expect
+    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+  end
+
+  config.disable_monkey_patching!
+end
+
+RSpec.shared_context "with #should enabled", :uses_should do
+  orig_syntax = nil
+
+  before(:all) do
+    orig_syntax = RSpec::Matchers.configuration.syntax
+    RSpec::Matchers.configuration.syntax = [:expect, :should]
+  end
+
+  after(:context) do
+    RSpec::Matchers.configuration.syntax = orig_syntax
+  end
+end
+
+RSpec.shared_context "with the default expectation syntax" do
+  orig_syntax = nil
+
+  before(:context) do
+    orig_syntax = RSpec::Matchers.configuration.syntax
+    RSpec::Matchers.configuration.reset_syntaxes_to_default
+  end
+
+  after(:context) do
+    RSpec::Matchers.configuration.syntax = orig_syntax
+  end
+
+end
+
+RSpec.shared_context "with #should exclusively enabled", :uses_only_should do
+  orig_syntax = nil
+
+  before(:context) do
+    orig_syntax = RSpec::Matchers.configuration.syntax
+    RSpec::Matchers.configuration.syntax = :should
+  end
+
+  after(:context) do
+    RSpec::Matchers.configuration.syntax = orig_syntax
+  end
+end
+
+RSpec.shared_context "isolate include_chain_clauses_in_custom_matcher_descriptions" do
+  around do |ex|
+    orig = RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions?
+    ex.run
+    RSpec::Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions = orig
+  end
+end
+
+require 'rspec/support/spec/in_sub_process'
+module MinitestIntegration
+  include ::RSpec::Support::InSubProcess
+
+  def with_minitest_loaded
+    in_sub_process do
+      with_isolated_stderr do
+        require 'minitest/autorun'
+      end
+
+      require 'rspec/expectations/minitest_integration'
+      yield
+    end
+  end
+end
diff --git a/rspec-expectations/spec/support/matchers.rb b/rspec-expectations/spec/support/matchers.rb
new file mode 100644
index 0000000..0a76c5b
--- /dev/null
+++ b/rspec-expectations/spec/support/matchers.rb
@@ -0,0 +1,55 @@
+RSpec::Matchers.define :include_method do |expected|
+  match do |actual|
+    actual.map { |m| m.to_s }.include?(expected.to_s)
+  end
+end
+
+RSpec::Matchers.define :custom_include do |*args|
+  match { |actual| expect(actual).to include(*args) }
+end
+
+RSpec::Matchers.define :be_a_clone_of do |expected|
+  match do |actual|
+    !actual.equal?(expected) &&
+        actual.class.equal?(expected.class) &&
+        state_of(actual) == state_of(expected)
+  end
+
+  def state_of(object)
+    ivar_names = object.instance_variables
+    Hash[ ivar_names.map { |n| [n, object.instance_variable_get(n)] } ]
+  end
+end
+
+RSpec::Matchers.define :have_string_length do |expected|
+  match do |actual|
+    @actual = actual
+    string_length == expected
+  end
+
+  def string_length
+    @string_length ||= @actual.length
+  end
+end
+
+module RSpec
+  module Matchers
+    def fail
+      raise_error(RSpec::Expectations::ExpectationNotMetError)
+    end
+
+    def fail_with(message)
+      raise_error(RSpec::Expectations::ExpectationNotMetError, message)
+    end
+
+    def fail_matching(message)
+      if String === message
+        regexp = /#{Regexp.escape(message)}/
+      else
+        regexp = message
+      end
+      raise_error(RSpec::Expectations::ExpectationNotMetError, regexp)
+    end
+  end
+end
+RSpec::Matchers.define_negated_matcher :a_string_excluding, :a_string_including
diff --git a/rspec-expectations/spec/support/shared_examples.rb b/rspec-expectations/spec/support/shared_examples.rb
new file mode 100644
index 0000000..5edf9b2
--- /dev/null
+++ b/rspec-expectations/spec/support/shared_examples.rb
@@ -0,0 +1,101 @@
+RSpec.shared_examples "an RSpec matcher" do |options|
+  let(:valid_value)   { options.fetch(:valid_value) }
+  let(:invalid_value) { options.fetch(:invalid_value) }
+
+  # Note: do not use `matcher` in 2 expectation expressions in a single
+  # example here. In some cases (such as `change { }.to(2)`), it will fail
+  # because using it a second time will apply `x += 2` twice, changing
+  # the value to 4.
+
+  it 'preserves the symmetric property of `==`' do
+    expect(matcher).to eq(matcher)
+    expect(matcher).not_to eq(valid_value)
+    expect(valid_value).not_to eq(matcher)
+  end
+
+  it 'matches a valid value when using #=== so it can be composed' do
+    expect(matcher).to be === valid_value
+  end
+
+  it 'does not match an invalid value when using #=== so it can be composed' do
+    expect(matcher).not_to be === invalid_value
+  end
+
+  matcher :always_passes do
+    supports_block_expectations
+    match do |actual|
+      actual.call if Proc === actual
+      true
+    end
+  end
+
+  matcher :always_fails do
+    supports_block_expectations
+    match do |actual|
+      actual.call if Proc === actual
+      false
+    end
+  end
+
+  it 'allows additional matchers to be chained off it using `and`' do
+    expect(valid_value).to matcher.and always_passes
+  end
+
+  it 'can be chained off of an existing matcher using `and`' do
+    expect(valid_value).to always_passes.and matcher
+  end
+
+  it 'allows additional matchers to be chained off it using `or`' do
+    expect(valid_value).to matcher.or always_fails
+  end
+
+  it 'can be chained off of an existing matcher using `or`' do
+    expect(valid_value).to always_fails.or matcher
+  end
+
+  it 'implements the full matcher protocol' do
+    expect(matcher).to respond_to(
+      :matches?,
+      :failure_message,
+      :description,
+      :supports_block_expectations?,
+      :expects_call_stack_jump?
+    )
+
+    # We do not require failure_message_when_negated and does_not_match?
+    # Because some matchers purposefully do not support negation.
+  end
+
+  it 'fails gracefully when given a value if it is a block matcher' do
+    if matcher.supports_block_expectations?
+      expect {
+        expect(3).to matcher
+      }.to fail_with(/was not( given)? a block/)
+
+      unless options[:disallows_negation]
+        expect {
+          expect(3).not_to matcher
+        }.to fail_with(/was not( given)? a block/)
+      end
+    end
+  end
+
+  it 'can be used in a composed matcher expression' do
+    expect([valid_value, invalid_value]).to include(matcher)
+
+    expect {
+      expect([invalid_value]).to include(matcher)
+    }.to fail_matching("include (#{matcher.description})")
+  end
+
+  it 'can match negatively properly' do
+    unless options[:disallows_negation]
+      expect(invalid_value).not_to matcher
+
+      expect {
+        expect(valid_value).not_to matcher
+      }.to fail
+    end
+  end
+end
+
diff --git a/rspec-mocks/.autotest b/rspec-mocks/.autotest
new file mode 100644
index 0000000..41607ff
--- /dev/null
+++ b/rspec-mocks/.autotest
@@ -0,0 +1,7 @@
+Autotest.add_hook :initialize do |at|
+  at.clear_mappings
+  at.add_mapping(%r%\.rb$%) {
+    at.files_matching %r%^spec/.*_spec\.rb$%
+  }
+end
+
diff --git a/rspec-mocks/.document b/rspec-mocks/.document
new file mode 100644
index 0000000..050e204
--- /dev/null
+++ b/rspec-mocks/.document
@@ -0,0 +1,5 @@
+lib/**/*.rb
+-
+README.md
+License.txt
+Changelog.md
diff --git a/rspec-mocks/.gitignore b/rspec-mocks/.gitignore
new file mode 100644
index 0000000..6859842
--- /dev/null
+++ b/rspec-mocks/.gitignore
@@ -0,0 +1,18 @@
+*.sw?
+.DS_Store
+coverage
+rdoc
+pkg
+doc
+tmp
+rerun.txt
+Gemfile.lock
+.bundle
+.idea
+*.rbc
+.yardoc
+bin
+Gemfile-custom
+bundle
+.rbx
+.rspec-local
diff --git a/rspec-mocks/.rspec b/rspec-mocks/.rspec
new file mode 100644
index 0000000..d0f7279
--- /dev/null
+++ b/rspec-mocks/.rspec
@@ -0,0 +1,2 @@
+--warnings
+--require spec_helper
diff --git a/rspec-mocks/.rubocop.yml b/rspec-mocks/.rubocop.yml
new file mode 100644
index 0000000..d2bde5d
--- /dev/null
+++ b/rspec-mocks/.rubocop.yml
@@ -0,0 +1,17 @@
+inherit_from: .rubocop_rspec_base.yml
+
+# This should go down over time.
+Style/ClassLength:
+  Max: 279
+
+# This should go down over time.
+Style/CyclomaticComplexity:
+  Max: 18
+
+# This should go down over time.
+Style/LineLength:
+  Max: 193
+
+# This should go down over time.
+Style/MethodLength:
+  Max: 49
diff --git a/rspec-mocks/.rubocop_rspec_base.yml b/rspec-mocks/.rubocop_rspec_base.yml
new file mode 100644
index 0000000..f7bea1c
--- /dev/null
+++ b/rspec-mocks/.rubocop_rspec_base.yml
@@ -0,0 +1,130 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# This file contains defaults for RSpec projects. Individual projects
+# can customize by inheriting this file and overriding particular settings.
+
+AccessModifierIndentation:
+  EnforcedStyle: outdent
+
+# "Use alias_method instead of alias"
+# We're fine with `alias`.
+Alias:
+  Enabled: false
+
+AlignParameters:
+  EnforcedStyle: with_first_parameter
+
+# "Avoid the use of the case equality operator ==="
+# We prefer using `Class#===` over `Object#is_a?` because `Class#===`
+# is less likely to be monkey patched than `is_a?` on a user object.
+CaseEquality:
+  Enabled: false
+
+# Warns when the class is excessively long.
+ClassLength:
+  Max: 100
+
+CollectionMethods:
+  PreferredMethods:
+    reduce: 'inject'
+
+# Over time we'd like to get this down, but this is what we're at now.
+CyclomaticComplexity:
+  Max: 10
+
+# We use YARD to enforce documentation. It works better than rubocop's
+# enforcement...rubocop complains about the places we re-open
+# `RSpec::Expectations` and `RSpec::Matchers` w/o having doc commments.
+Documentation:
+  Enabled: false
+
+# We still support 1.8.7 which requires trailing dots
+DotPosition:
+  EnforcedStyle: trailing
+
+DoubleNegation:
+  Enabled: false
+
+# each_with_object is unavailable on 1.8.7 so we have to disable this one.
+EachWithObject:
+  Enabled: false
+
+Encoding:
+  EnforcedStyle: when_needed
+
+FormatString:
+  EnforcedStyle: percent
+
+# As long as we support ruby 1.8.7 we have to use hash rockets.
+HashSyntax:
+  EnforcedStyle: hash_rockets
+
+# We can't use the new lambda syntax, since we still support 1.8.7.
+Lambda:
+  Enabled: false
+
+# Over time we'd like to get this down, but this is what we're at now.
+LineLength:
+  Max: 100
+
+# Over time we'd like to get this down, but this is what we're at now.
+MethodLength:
+  Max: 15
+
+# Who cares what we call the argument for binary operator methods?
+OpMethod:
+  Enabled: false
+
+PercentLiteralDelimiters:
+  PreferredDelimiters:
+    '%':  ()      # double-quoted string
+    '%i': '[]'    # array of symbols
+    '%q': ()      # single-quoted string
+    '%Q': ()      # double-quoted string
+    '%r': '{}'    # regular expression pattern
+    '%s': ()      # a symbol
+    '%w': '[]'    # array of single-quoted strings
+    '%W': '[]'    # array of double-quoted strings
+    '%x': ()      # a shell command as a string
+
+# We have too many special cases where we allow generator methods or prefer a
+# prefixed predicate due to it's improved readability.
+PredicateName:
+  Enabled: false
+
+# On 1.8 `proc` is `lambda`, so we use `Proc.new` to ensure we get real procs on all supported versions.
+# http://batsov.com/articles/2014/02/04/the-elements-of-style-in-ruby-number-12-proc-vs-proc-dot-new/
+Proc:
+  Enabled: false
+
+RedundantReturn:
+  AllowMultipleReturnValues: true
+
+# We have to rescue Exception in the `raise_error` matcher for it to work properly.
+RescueException:
+  Enabled: false
+
+# We haven't adopted the `fail` to signal exceptions vs `raise` for re-raises convention.
+SignalException:
+  Enabled: false
+
+# We've tended to use no space, so it's less of a change to stick with that.
+SpaceAroundEqualsInParameterDefault:
+  EnforcedStyle: no_space
+
+# We don't care about single vs double qoutes.
+StringLiterals:
+  Enabled: false
+
+# This rule favors constant names from the English standard library which we don't load.
+Style/SpecialGlobalVars:
+  Enabled: false
+
+Style/TrailingComma:
+  Enabled: false
+
+TrivialAccessors:
+  AllowDSLWriters: true
+  AllowPredicates: true
+  ExactNameMatch: true
diff --git a/rspec-mocks/.travis.yml b/rspec-mocks/.travis.yml
new file mode 100644
index 0000000..ea4f1b0
--- /dev/null
+++ b/rspec-mocks/.travis.yml
@@ -0,0 +1,37 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+language: ruby
+sudo: false
+cache:
+  directories:
+    - ../bundle
+before_install:
+  - "script/clone_all_rspec_repos"
+  # Downgrade bundler to work around https://github.com/bundler/bundler/issues/3004
+  # Note this doesn't work on JRUBY 2.0.0 mode so we don't do it
+  - if [ -z "$JRUBY_OPTS" ]; then gem install bundler -v=1.5.3 && alias bundle="bundle _1.5.3_"; fi
+bundler_args: "--binstubs --standalone --without documentation --path ../bundle"
+script: "script/run_build"
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - 2.1
+  - 2.2
+  - ruby-head
+  - ree
+  - jruby-18mode
+  - jruby
+  - jruby-head
+  - rbx
+matrix:
+  include:
+    - rvm: jruby
+      env: JRUBY_OPTS='--2.0'
+  allow_failures:
+    - rvm: jruby-head
+    - rvm: ruby-head
+    - rvm: rbx
+  fast_finish: true
diff --git a/rspec-mocks/.yardopts b/rspec-mocks/.yardopts
new file mode 100644
index 0000000..15f63ee
--- /dev/null
+++ b/rspec-mocks/.yardopts
@@ -0,0 +1,6 @@
+--exclude features
+--no-private
+--markup markdown
+-
+Changelog.md
+License.txt
diff --git a/rspec-mocks/Changelog.md b/rspec-mocks/Changelog.md
new file mode 100644
index 0000000..40dd764
--- /dev/null
+++ b/rspec-mocks/Changelog.md
@@ -0,0 +1,893 @@
+### 3.2.1 / 2015-02-23
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.0...v3.2.1)
+
+Bug Fixes:
+
+* Add missing `rspec/support/differ` require so that rspec-mocks can be
+  used w/o rspec-expectations (which also loads the differ and hided the
+  fact we forgot to require it). (Myron Marston, #893)
+* Revert tracking of received arg mutation (added in 3.2.0 to provide an
+  error in a situation we can't support) as our implementation has side
+  effects on non-standard objects and there's no solution we could come
+  up with that always works. (Myron Marston, #900)
+
+### 3.2.0 / 2015-02-03
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.3...v3.2.0)
+
+Enhancements:
+
+* Treat `any_args` as an arg splat, allowing it to match an arbitrary
+  number of args at any point in an arg list. (Myron Marston, #786)
+* Print diffs when arguments in mock expectations are mismatched.
+  (Sam Phippen, #751)
+* Support names for verified doubles (`instance_double`, `instance_spy`,
+  `class_double`, `class_spy`, `object_double`, `object_spy`). (Cezary
+  Baginski, #826)
+* Make `array_including` and `hash_including` argument matchers composable.
+  (Sam Phippen, #819)
+* Make `allow_any_instance_of(...).to receive(...).and_wrap_original`
+  work. (Ryan Fitzgerald, #869)
+
+Bug Fixes:
+
+* Provide a clear error when users wrongly combine `no_args` with
+  additional arguments (e.g. `expect().to receive().with(no_args, 1)`).
+  (Myron Marston, #786)
+* Provide a clear error when users wrongly use `any_args` multiple times in the
+  same argument list (e.g. `expect().to receive().with(any_args, 1, any_args)`.
+  (Myron Marston, #786)
+* Prevent the error generator from using user object #description methods.
+  See [#685](https://github.com/rspec/rspec-mocks/issues/685).
+  (Sam Phippen, #751)
+* Make verified doubles declared as `(instance|class)_double(SomeConst)`
+  work properly when `SomeConst` has previously been stubbed.
+  `(instance|class)_double("SomeClass")` already worked properly.
+  (Myron Marston, #824)
+* Add a matcher description for `receive`, `receive_messages` and
+  `receive_message_chain`. (Myron Marston, #828)
+* Validate invocation args for null object verified doubles.
+  (Myron Marston, #829)
+* Fix `RSpec::Mocks::Constant.original` when called with an invalid
+  constant to return an object indicating the constant name is invalid,
+  rather than blowing up. (Myron Marston, #833)
+* Make `extend RSpec::Mocks::ExampleMethods` on any object work properly
+  to add the rspec-mocks API to that object. Previously, `expect` would
+  be undefined. (Myron Marston, #846)
+* Fix `require 'rspec/mocks/standalone'` so that it only affects `main`
+  and not every object. It's really only intended to be used in a REPL
+  like IRB, but some gems have loaded it, thinking it needs to be loaded
+  when using rspec-mocks outside the context of rspec-core.
+  (Myron Marston, #846)
+* Prevent message expectations from being modified by customization methods
+  (e.g. `with`) after they have been invoked. (Sam Phippen and Melanie Gilman, #837)
+* Handle cases where a method stub cannot be removed due to something
+  external to RSpec monkeying with the method definition. This can
+  happen, for example, when you `file.reopen(io)` after previously
+  stubbing a method on the `file` object. (Myron Marston, #853)
+* Provide a clear error when received message args are mutated before
+  a `have_received(...).with(...)` expectation. (Myron Marston, #868)
+
+### 3.1.3 / 2014-10-08
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.2...v3.1.3)
+
+Bug Fixes:
+
+* Correct received messages count when used with `have_received` matcher.
+  (Jon Rowe, #793)
+* Provide a clear error message when you use `allow_any_instance_of(...)` or
+  `expect_any_instance_of(...)` with the `have_received` matcher (they are
+  not intended to be used together and previously caused an odd internal
+  failure in rspec-mocks). (Jon Rowe, #799).
+* Fix verified double `with` verification so that it applies to method
+  stubs. (Myron Marston, #790)
+
+### 3.1.2 / 2014-09-26
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.1...v3.1.2)
+
+Bug Fixes:
+
+* Provide a clear error message when you use `allow(...)` with the
+  `have_received` matcher (they are not intended to be used together
+  and previously caused an odd internal failure in rspec-mocks). (Jon Rowe, #788).
+
+### 3.1.1 / 2014-09-18
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.0...v3.1.1)
+
+Bug Fixes:
+
+* Prevent included modules being detected as prepended modules on Ruby 2.0
+  when using `any_instance_of(...)`. (Tony Novak, #781)
+
+### 3.1.0 / 2014-09-04
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.4...v3.1.0)
+
+Enhancements:
+
+* Add spying methods (`spy`, `ìnstance_spy`, `class_spy` and `object_spy`)
+  which create doubles as null objects for use with spying in testing. (Sam
+  Phippen, #671)
+* `have_received` matcher will raise "does not implement" errors correctly when
+  used with verifying doubles and partial doubles. (Xavier Shay, #722)
+* Allow matchers to be used in place of keyword arguments in `with`
+  expectations. (Xavier Shay, #726)
+* Add `thrice` modifier to message expectation interface as a synonym
+  for `exactly(3).times`. (Dennis Taylor, #753)
+* Add more `thrice` synonyms e.g. `.at_least(:thrice)`, `.at_most(:thrice)`,
+  `receive(...).thrice` and `have_received(...).thrice`. (Jon Rowe, #754)
+* Add `and_wrap_original` modifier for partial doubles to mutate the
+  response from a method. (Jon Rowe, #762)
+
+Bug Fixes:
+
+* Remove `any_number_of_times` from `any_instance` recorders that were
+  erroneously causing mention of the method in documentation. (Jon Rowe, #760)
+* Prevent included modules being detected as prepended modules on Ruby 2.0.
+  (Eugene Kenny, #771)
+
+### 3.0.4 / 2014-08-14
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.3...v3.0.4)
+
+Bug Fixes:
+
+* Restore `kind_of(x)` to match using `arg.kind_of?(x)` (like RSpec 2)
+  rather than `x === arg`. (Jon Rowe, #750)
+
+### 3.0.3 / 2014-07-21
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.2...v3.0.3)
+
+Bug Fixes:
+
+* `have_received` matcher will raise "does not implement" errors correctly when
+  used with verifying doubles and partial doubles. (Xavier Shay, #722)
+* Make `double.as_null_object.dup` and `double.as_null_object.clone`
+  make the copies be null objects. (Myron Marston, #732)
+* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, #739)
+
+### 3.0.2 / 2014-06-19
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.1...v3.0.2)
+
+Bug Fixes:
+
+* Fix edge case that triggered "can't add a new key into hash during
+  iteration" during mock verification. (Sam Phippen, Myron Marston, #711)
+* Fix verifying doubles so that when they accidentally leak into another
+  example, they provide the same clear error message that normal doubles
+  do. (Myron Marston, #718)
+* Make `ordered` work with exact receive counts. (Sam Phippen, #713)
+
+### 3.0.1 / 2014-06-07
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0...v3.0.1)
+
+Bug Fixes:
+
+* Fix `receive_message_chain(...)` so that it supports `with` just like
+  `stub_chain` did. (Jon Rowe, #697)
+* Fix regression in `expect_any_instance_of` so that it expects the
+  message on _any_ instance rather than on _every_ instance.
+  (Myron Marston, #699)
+
+### 3.0.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.rc1...v3.0.0)
+
+Bug Fixes:
+
+* Fix module prepend detection to work properly on ruby 2.0 for a case
+  where a module is extended onto itself. (Myron Marston)
+* Fix `transfer_nested_constants` option so that transferred constants
+  get properly reset at the end of the example. (Myron Marston)
+* Fix `config.transfer_nested_constants = true` so that you don't
+  erroneously get errors when stubbing a constant that is not a module
+  or a class. (Myron Marston)
+* Fix regression that caused `double(:class => SomeClass)` to later
+  trigger infinite recursion. (Myron Marston)
+* Fix bug in `have_received(...).with(...).ordered` where it was not
+  taking the args into account when checking the order. (Myron Marston)
+* Fix bug in `have_received(...).ordered` where it was wrongly
+  considering stubs when checking the order. (Myron Marston)
+* Message expectation matchers now show descriptions from argument
+  matchers when their expectations aren't met. (Jon Rowe)
+* Display warning when encountering `TypeError` during instance method
+  staging on 2.0.0-p195, suffers from https://bugs.ruby-lang.org/issues/8686
+  too. (Cezar Halmagean).
+
+### 3.0.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta2...v3.0.0.rc1)
+
+Breaking Changes for 3.0.0:
+
+* Remove `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston)
+* Remove `RSpec::Mocks::ConstantStubber`. (Jon Rowe)
+* Make monkey-patch of Marshal to support dumping of stubbed objects opt-in.
+  (Xavier Shay)
+
+Enhancements:
+
+* Instead of crashing when cleaning up stub methods on a frozen object, it now
+  issues a warning explaining that it's impossible to clean up the stubs.
+  (Justin Coyne and Sam Phippen)
+* Add meaningful descriptions to `anything`, `duck_type` and `instance_of` argument
+  matchers. (Jon Rowe)
+
+Bug Fixes:
+
+* Fix regression introduced in 3.0.0.beta2 that caused
+  `double.as_null_object.to_str` to return the double rather
+  than a string. (Myron Marston)
+* Fix bug in `expect(dbl).to receive_message_chain(:foo, :bar)` where it was
+  not setting an expectation for the last message in the chain.
+  (Jonathan del Strother)
+* Allow verifying partial doubles to have private methods stubbed. (Xavier Shay)
+* Fix bug with allowing/expecting messages on Class objects which have had
+  their singleton class prepended to. (Jon Rowe)
+* Fix an issue with 1.8.7 not running implementation blocks on partial doubles.
+  (Maurício Linhares)
+* Prevent `StackLevelTooDeep` errors when stubbing an `any_instance` method that's
+  accessed in `inspect` by providing our own inspect output. (Jon Rowe)
+* Fix bug in `any_instance` logic that did not allow you to mock or stub
+  private methods if `verify_partial_doubles` was configured. (Oren Dobzinski)
+* Include useful error message when trying to observe an unimplemented method
+  on an any instance. (Xavier Shay)
+* Fix `and_call_original` to work properly when multiple classes in an
+  inheritance hierarchy have been stubbed with the same method. (Myron Marston)
+* Fix `any_instance` so that it updates existing instances that have
+  already been stubbed. (Myron Marston)
+* Fix verified doubles so that their class name is included in failure
+  messages. (Myron Marston)
+* Fix `expect_any_instance_of` so that when the message is received
+  on an individual instance that has been directly stubbed, it still
+  satisfies the expectation. (Sam Phippen, Myron Marston)
+* Explicitly disallow using `any_instance` to mock or stub a method
+  that is defined on a module prepended onto the class. This triggered
+  `SystemStackError` before and is very hard to support so we are not
+  supporting it at this time. (Myron Marston)
+
+### 3.0.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta1...v3.0.0.beta2)
+
+Breaking Changes for 3.0.0:
+
+* Rename `RSpec::Mocks::Mock` to `RSpec::Mocks::Double`. (Myron Marston)
+* Change how to integrate rspec-mocks in other test frameworks. You now
+  need to include `RSpec::Mocks::ExampleMethods` in your test context.
+  (Myron Marston)
+* Prevent RSpec mocks' doubles and partial doubles from being used outside of
+  the per-test lifecycle (e.g. from a `before(:all)` hook). (Sam Phippen)
+* Remove the `host` argument of `RSpec::Mocks.setup`. Instead
+  `RSpec::Mocks::ExampleMethods` should be included directly in the scope where
+  RSpec's mocking capabilities are used. (Sam Phippen)
+* Make test doubles raise errors if you attempt to use them after they
+  get reset, to help surface issues when you accidentally retain
+  references to test doubles and attempt to reuse them in another
+  example. (Myron Marston)
+* Remove support for `and_return { value }` and `and_return` without arguments. (Yuji Nakayama)
+
+Enhancements:
+
+* Add `receive_message_chain` which provides the functionality of the old
+  `stub_chain` for the new allow/expect syntax. Use it like so: `allow(...).to
+  receive_message_chain(:foo, :bar, :bazz)`. (Sam Phippen).
+* Change argument matchers to use `===` as their primary matching
+  protocol, since their semantics mirror that of a case or rescue statement
+  (which uses `===` for matching). (Myron Marston)
+* Add `RSpec::Mocks.with_temporary_scope`, which allows you to create
+  temporary rspec-mocks scopes in arbitrary places (such as a
+  `before(:all)` hook). (Myron Marston)
+* Support keyword arguments when checking arity with verifying doubles.
+  (Xavier Shay)
+
+Bug Fixes:
+
+* Fix regression in 3.0.0.beta1 that caused `double("string_name" => :value)`
+  to stop working. (Xavier Shay)
+* Fix the way rspec-mocks and rspec-core interact so that if users
+  define a `let` with the same name as one of the methods
+  from `RSpec::Mocks::ArgumentMatchers`, the user's `let` takes
+  precedence. (Michi Huber, Myron Marston)
+* Fix verified doubles so that their methods match the visibility
+  (public, protected or private) of the interface they verify
+  against. (Myron Marston)
+* Fix verified null object doubles so that they do not wrongly
+  report that they respond to anything. They only respond to methods
+  available on the interface they verify against. (Myron Marston)
+* Fix deprecation warning for use of old `:should` syntax w/o explicit
+  config so that it no longer is silenced by an extension gem such
+  as rspec-rails when it calls `config.add_stub_and_should_receive_to`.
+  (Sam Phippen)
+* Fix `expect` syntax so that it does not wrongly emit a "You're
+  overriding a previous implementation for this stub" warning when
+  you are not actually doing that. (Myron Marston)
+* Fix `any_instance.unstub` when used on sub classes for whom the super
+  class has had `any_instance.stub` invoked on. (Jon Rowe)
+* Fix regression in `stub_chain`/`receive_message_chain` that caused
+  it to raise an `ArgumentError` when passing args to the stubbed
+  methods. (Sam Phippen)
+* Correct stub of undefined parent modules all the way down when stubbing a
+  nested constant. (Xavier Shay)
+* Raise `VerifyingDoubleNotDefinedError` when a constant is not defined for
+  a verifying class double. (Maurício Linhares)
+* Remove `Double#to_str`, which caused confusing `raise some_double`
+  behavior. (Maurício Linhares)
+
+### 3.0.0.beta1 / 2013-11-07
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.3...v3.0.0.beta1)
+
+Breaking Changes for 3.0.0:
+
+* Raise an explicit error if `should_not_receive(...).and_return` is used. (Sam
+  Phippen)
+* Remove 1.8.6 workarounds. (Jon Rowe)
+* Remove `stub!` and `unstub!`. (Sam Phippen)
+* Remove `mock(name, methods)` and `stub(name, methods)`, leaving
+  `double(name, methods)` for creating test doubles. (Sam Phippen, Michi Huber)
+* Remove `any_number_of_times` since `should_receive(:msg).any_number_of_times`
+  is really a stub in a mock's clothing. (Sam Phippen)
+* Remove support for re-using the same null-object test double in multiple
+  examples.  Test doubles are designed to only live for one example.
+  (Myron Marston)
+* Make `at_least(0)` raise an error. (Sam Phippen)
+* Remove support for `require 'spec/mocks'` which had been kept
+  in place for backwards compatibility with RSpec 1. (Myron Marston)
+* Blocks provided to `with` are always used as implementation. (Xavier Shay)
+* The config option (added in 2.99) to yield the receiver to
+  `any_instance` implementation blocks now defaults to "on". (Sam Phippen)
+
+Enhancements:
+
+* Allow the `have_received` matcher to use a block to set further expectations
+  on arguments. (Tim Cowlishaw)
+* Provide `instance_double` and `class_double` to create verifying doubles,
+  ported from `rspec-fire`. (Xavier Shay)
+* `as_null_object` on a verifying double only responds to defined methods.
+  (Xavier Shay)
+* Provide `object_double` to create verified doubles of specific object
+  instances. (Xavier Shay)
+* Provide `verify_partial_doubles` configuration that provides `object_double`
+  like verification behaviour on partial doubles. (Xavier Shay)
+* Improved performance of double creation, particularly those with many
+  attributes. (Xavier Shay)
+* Default value of `transfer_nested_constants` option for constant stubbing can
+  be configured. (Xavier Shay)
+* Messages can be allowed or expected on in bulk via
+  `receive_messages(:message => :value)`. (Jon Rowe)
+* `allow(Klass.any_instance)` and `expect(Klass.any_instance)` now print a
+  warning. This is usually a mistake, and users usually want
+  `allow_any_instance_of` or `expect_any_instance_of` instead. (Sam Phippen)
+* `instance_double` and `class_double` raise `ArgumentError` if the underlying
+  module is loaded and the arity of the method being invoked does not match the
+  arity of the method as it is actually implemented. (Andy Lindeman)
+* Spies can now check their invocation ordering is correct. (Jon Rowe)
+
+Deprecations:
+
+* Using the old `:should` syntax without explicitly configuring it
+  is deprecated. It will continue to work but will emit a deprecation
+  warning in RSpec 3 if you do not explicitly enable it. (Sam Phippen)
+
+Bug Fixes:
+
+* Fix `and_call_original` to handle a complex edge case involving
+  singleton class ancestors. (Marc-André Lafortune, Myron Marston)
+* When generating an error message for unexpected arguments,
+  use `#inspect` rather than `#description` if `#description`
+  returns `nil` or `''` so that you still get a useful message.
+  (Nick DeLuca)
+
+### 2.99.3 / 2015-01-09
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.2...v2.99.3)
+
+Bug Fixes:
+
+* Fix regression that caused an error when a test double was deserialized from YAML. (Yuji Nakayama, #777)
+
+### 2.99.2 / 2014-07-21
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.1...v2.99.2)
+
+Enhancements:
+
+* Warn about upcoming change to `#===` matching and `DateTime#===` behaviour.
+  (Jon Rowe, #735)
+
+### 2.99.1 / 2014-06-12
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0...v2.99.1)
+
+Bug Fixes:
+
+* Fix bug that caused errors at the end of each example
+  when a `double.as_null_object` had been frozen. (Yuji Nakayama, #698)
+
+Deprecations:
+
+* Deprecate freezing a test double. (Yuji Nakayama, #698)
+
+### 2.99.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.rc1...v2.99.0)
+
+No changes. Just taking it out of pre-release.
+
+### 2.99.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta2...v2.99.0.rc1)
+
+Deprecations:
+
+* Deprecate `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston)
+* Deprecate `RSpec::Mocks::ConstantStubber`. (Jon Rowe)
+* Deprecate `Marshal.dump` monkey-patch without opt-in. (Xavier Shay)
+
+### 2.99.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta1...v2.99.0.beta2)
+
+Deprecations:
+
+* Deprecate `RSpec::Mocks::Mock` in favor of `RSpec::Mocks::Double`.
+  (Myron Marston)
+* Deprecate the `host` argument of `RSpec::Mocks.setup`. Instead
+  `RSpec::Mocks::ExampleMethods` should be included directly in the scope where
+  RSpec's mocking capabilities are used. (Sam Phippen)
+* Deprecate using any of rspec-mocks' features outside the per-test
+  lifecycle (e.g. from a `before(:all)` hook). (Myron Marston)
+* Deprecate re-using a test double in another example. (Myron Marston)
+* Deprecate `and_return { value }` and `and_return` without arguments. (Yuji Nakayama)
+
+### 2.99.0.beta1 / 2013-11-07
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.99.0.beta1)
+
+Deprecations
+
+* Expecting to use lambdas or other strong arity implementations for stub
+  methods with mis-matched arity is deprecated and support for them will be
+  removed in 3.0. Either provide the right amount of arguments or use a weak
+  arity implementation (methods with splats or procs). (Jon Rowe)
+* Using the same test double instance in multiple examples is deprecated. Test
+  doubles are only meant to live for one example. The mocks and stubs have
+  always been reset between examples; however, in 2.x the `as_null_object`
+  state was not reset and some users relied on this to have a null object
+  double that is used for many examples. This behavior will be removed in 3.0.
+  (Myron Marston)
+* Print a detailed warning when an `any_instance` implementation block is used
+  when the new `yield_receiver_to_any_instance_implementation_blocks` config
+  option is not explicitly set, as RSpec 3.0 will default to enabling this new
+  feature. (Sam Phippen)
+
+Enhancements:
+
+* Add a config option to yield the receiver to `any_instance` implementation
+  blocks. (Sam Phippen)
+
+### 2.14.6 / 2014-02-20
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.5...v2.14.6)
+
+Bug Fixes:
+
+* Ensure `any_instance` method stubs and expectations are torn down regardless of
+  expectation failures. (Sam Phippen)
+
+### 2.14.5 / 2014-02-01
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.14.5)
+
+Bug Fixes:
+
+* Fix regression that caused block implementations to not receive all
+  args on 1.8.7 if the block also receives a block, due to Proc#arity
+  reporting `1` no matter how many args the block receives if it
+  receives a block, too. (Myron Marston)
+
+### 2.14.4 / 2013-10-15
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.3...v2.14.4)
+
+Bug Fixes:
+
+* Fix issue where unstubing methods on "any instances" would not
+  remove stubs on existing instances (Jon Rowe)
+* Fix issue with receive(:message) do ... end precedence preventing
+  the usage of modifications (`and_return` etc) (Jon Rowe)
+
+### 2.14.3 / 2013-08-08
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.2...v2.14.3)
+
+Bug Fixes:
+
+* Fix stubbing some instance methods for classes whose hierarchy includes
+  a prepended Module (Bradley Schaefer)
+
+### 2.14.2 / 2013-07-30
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.1...v2.14.2)
+
+Bug Fixes:
+
+* Fix `as_null_object` doubles so that they return `nil` from `to_ary`
+  (Jon Rowe).
+* Fix regression in 2.14 that made `stub!` (with an implicit receiver)
+  return a test double rather than stub a method (Myron Marston).
+
+### 2.14.1 / 2013-07-07
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0...v2.14.1)
+
+Bug Fixes:
+
+* Restore `double.as_null_object` behavior from 2.13 and earlier: a
+  double's nullness persisted between examples in earlier examples.
+  While this is not an intended use case (test doubles are meant to live
+  for only one example), we don't want to break behavior users rely
+  on in a minor relase.  This will be deprecated in 2.99 and removed
+  in 3.0. (Myron Marston)
+
+### 2.14.0 / 2013-07-06
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0.rc1...v2.14.0)
+
+Enhancements:
+
+* Document test spies in the readme. (Adarsh Pandit)
+* Add an `array_including` matcher. (Sam Phippen)
+* Add a syntax-agnostic API for mocking or stubbing a method. This is
+  intended for use by libraries such as rspec-rails that need to mock
+  or stub a method, and work regardless of the syntax the user has
+  configured (Paul Annesley, Myron Marston and Sam Phippen).
+
+Bug Fixes:
+
+* Fix `double` so that it sets up passed stubs correctly regardless of
+  the configured syntax (Paul Annesley).
+* Allow a block implementation to be used in combination with
+  `and_yield`, `and_raise`, `and_return` or `and_throw`. This got fixed
+  in 2.13.1 but failed to get merged into master for the 2.14.0.rc1
+  release (Myron Marston).
+* `Marshal.dump` does not unnecessarily duplicate objects when rspec-mocks has
+  not been fully initialized. This could cause errors when using `spork` or
+  similar preloading gems (Andy Lindeman).
+
+### 2.14.0.rc1 / 2013-05-27
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.14.0.rc1)
+
+Enhancements:
+
+* Refactor internals so that the mock proxy methods and state are held
+  outside of the mocked object rather than inside it. This paves the way
+  for future syntax enhancements and removes the need for some hacky
+  work arounds for `any_instance` dup'ing and `YAML` serialization,
+  among other things. Note that the code now relies upon `__id__`
+  returning a unique, consistent value for any object you want to
+  mock or stub (Myron Marston).
+* Add support for test spies. This allows you to verify a message
+  was received afterwards using the `have_received` matcher.
+  Note that you must first stub the method or use a null double.
+  (Joe Ferris and Joël Quenneville)
+* Make `at_least` and `at_most` style receive expectations print that they were
+  expecting at least or at most some number of calls, rather than just the
+  number of calls given in the expectation (Sam Phippen)
+* Make `with` style receive expectations print the args they were expecting, and
+  the args that they got (Sam Phippen)
+* Fix some warnings seen under ruby 2.0.0p0 (Sam Phippen).
+* Add a new `:expect` syntax for message expectations
+  (Myron Marston and Sam Phippen).
+
+Bug fixes
+
+* Fix `any_instance` so that a frozen object can be `dup`'d when methods
+  have been stubbed on that type using `any_instance` (Jon Rowe).
+* Fix `and_call_original` so that it properly raises an `ArgumentError`
+  when the wrong number of args are passed (Jon Rowe).
+* Fix `double` on 1.9.2 so you can wrap them in an Array
+  using `Array(my_double)` (Jon Rowe).
+* Fix `stub_const` and `hide_const` to handle constants that redefine `send`
+  (Sam Phippen).
+* Fix `Marshal.dump` extension so that it correctly handles nil.
+  (Luke Imhoff, Jon Rowe)
+* Fix isolation of `allow_message_expectations_on_nil` (Jon Rowe)
+* Use inspect to format actual arguments on expectations in failure messages (#280, Ben Langfeld)
+* Protect against improperly initialised test doubles (#293) (Joseph Shraibman and Jon Rowe)
+
+Deprecations
+
+* Deprecate `stub` and `mock` as aliases for `double`. `double` is the
+  best term for creating a test double, and it reduces confusion to
+  have only one term (Michi Huber).
+* Deprecate `stub!` and `unstub!` in favor of `stub` and `unstub`
+  (Jon Rowe).
+* Deprecate `at_least(0).times` and `any_number_of_times` (Michi Huber).
+
+### 2.13.1 / 2013-04-06
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.13.1)
+
+Bug fixes
+
+* Allow a block implementation to be used in combination with
+  `and_yield`, `and_raise`, `and_return` or `and_throw` (Myron Marston).
+
+### 2.13.0 / 2013-02-23
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.2...v2.13.0)
+
+Bug fixes
+
+* Fix bug that caused weird behavior when a method that had
+  previously been stubbed with multiple return values (e.g.
+  `obj.stub(:foo).and_return(1, 2)`) was later mocked with a
+  single return value (e.g. `obj.should_receive(:foo).once.and_return(1)`).
+  (Myron Marston)
+* Fix bug related to a mock expectation for a method that already had
+  multiple stubs with different `with` constraints. Previously, the
+  first stub was used, even though it may not have matched the passed
+  args. The fix defers this decision until the message is received so
+  that the proper stub response can be chosen based on the passed
+  arguments (Myron Marston).
+* Do not call `nil?` extra times on a mocked object, in case `nil?`
+  itself is expected a set number of times (Myron Marston).
+* Fix `missing_default_stub_error` message so array args are handled
+  properly (Myron Marston).
+* Explicitly disallow `any_instance.unstub!` (Ryan Jones).
+* Fix `any_instance` stubbing so that it works with `Delegator`
+  subclasses (Myron Marston).
+* Fix `and_call_original` so that it works with `Delegator` subclasses
+  (Myron Marston).
+* Fix `any_instance.should_not_receive` when `any_instance.should_receive`
+  is used on the same class in the same example. Previously it would
+  wrongly report a failure even when the message was not received
+  (Myron Marston).
+
+### 2.12.2 / 2013-01-27
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.1...v.2.12.2)
+
+Bug fixes
+
+* Fix `and_call_original` to work properly for methods defined
+  on a module extended onto an object instance (Myron Marston).
+* Fix `stub_const` with an undefined constnat name to work properly
+  with constant strings that are prefixed with `::` -- and edge case
+  I missed in the bug fix in the 2.12.1 release (Myron Marston).
+* Ensure method visibility on a partial mock is restored after reseting
+  method stubs, even on a singleton module (created via `extend self`)
+  when the method visibility differs between the instance and singleton
+  versions (Andy Lindeman).
+
+### 2.12.1 / 2012-12-21
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.0...v2.12.1)
+
+Bug fixes
+
+* Fix `any_instance` to support `and_call_original`.
+  (Myron Marston)
+* Properly restore stubbed aliased methods on rubies
+  that report the incorrect owner (Myron Marston and Andy Lindeman).
+* Fix `hide_const` and `stub_const` with a defined constnat name to
+  work properly with constant strings that are prefixed with `::` (Myron Marston).
+
+### 2.12.0 / 2012-11-12
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.3...v2.12.0)
+
+Enhancements
+
+* `and_raise` can accept an exception class and message, more closely
+  matching `Kernel#raise` (e.g., `foo.stub(:bar).and_raise(RuntimeError, "message")`)
+  (Bas Vodde)
+* Add `and_call_original`, which will delegate the message to the
+  original method (Myron Marston).
+
+Deprecations:
+
+* Add deprecation warning when using `and_return` with `should_not_receive`
+  (Neha Kumari)
+
+### 2.11.3 / 2012-09-19
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.2...v2.11.3)
+
+Bug fixes
+
+* Fix `:transfer_nested_constants` option of `stub_const` so that it
+  doesn't blow up when there are inherited constants. (Myron Marston)
+* `any_instance` stubs can be used on classes that override `Object#method`.
+  (Andy Lindeman)
+* Methods stubbed with `any_instance` are unstubbed after the test finishes.
+  (Andy Lindeman)
+* Fix confusing error message when calling a mocked class method an
+  extra time with the wrong arguments (Myron Marston).
+
+### 2.11.2 / 2012-08-11
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.1...v2.11.2)
+
+Bug fixes
+
+* Don't modify `dup` on classes that don't support `dup` (David Chelimsky)
+* Fix `any_instance` so that it works properly with methods defined on
+  a superclass. (Daniel Eguzkiza)
+* Fix `stub_const` so that it works properly for nested constants that
+  share a name with a top-level constant (e.g. "MyGem::Hash"). (Myron
+  Marston)
+
+### 2.11.1 / 2012-07-09
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.0...v2.11.1)
+
+Bug fixes
+
+* Fix `should_receive` so that when it is called on an `as_null_object`
+  double with no implementation, and there is a previous explicit stub
+  for the same method, the explicit stub remains (rather than being
+  overriden with the null object implementation--`return self`). (Myron Marston)
+
+### 2.11.0 / 2012-07-07
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.1...v2.11.0)
+
+Enhancements
+
+* Expose ArgumentListMatcher as a formal API
+    * supports use by 3rd party mock frameworks like Surrogate
+* Add `stub_const` API to stub constants for the duration of an
+  example (Myron Marston).
+
+Bug fixes
+
+* Fix regression of edge case behavior. `double.should_receive(:foo) { a }`
+  was causing a NoMethodError when `double.stub(:foo).and_return(a, b)`
+  had been setup before (Myron Marston).
+* Infinite loop generated by using `any_instance` and `dup`. (Sidu Ponnappa @kaiwren)
+* `double.should_receive(:foo).at_least(:once).and_return(a)` always returns a
+  even if `:foo` is already stubbed.
+* Prevent infinite loop when interpolating a null double into a string
+  as an integer (`"%i" % double.as_null_object`). (Myron Marston)
+* Fix `should_receive` so that null object behavior (e.g. returning
+  self) is preserved if no implementation is given (Myron Marston).
+* Fix `and_raise` so that it raises `RuntimeError` rather than
+  `Exception` by default, just like ruby does. (Andrew Marshall)
+
+### 2.10.1 / 2012-05-05
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.0...v2.10.1)
+
+Bug fixes
+
+* fix regression of edge case behavior
+  (https://github.com/rspec/rspec-mocks/issues/132)
+    * fixed failure of `object.should_receive(:message).at_least(0).times.and_return value`
+    * fixed failure of `object.should_not_receive(:message).and_return value`
+
+### 2.10.0 / 2012-05-03
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.9.0...v2.10.0)
+
+Bug fixes
+
+* fail fast when an `exactly` or `at_most` expectation is exceeded
+
+### 2.9.0 / 2012-03-17
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0...v2.9.0)
+
+Enhancements
+
+* Support order constraints across objects (preethiramdev)
+
+Bug fixes
+
+* Allow a `as_null_object` to be passed to `with`
+* Pass proc to block passed to stub (Aubrey Rhodes)
+* Initialize child message expectation args to match any args (#109 -
+  preethiramdev)
+
+### 2.8.0 / 2012-01-04
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc2...v2.8.0)
+
+No changes for this release. Just releasing with the other rspec gems.
+
+### 2.8.0.rc2 / 2011-12-19
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc1...v2.8.0.rc2)
+
+No changes for this release. Just releasing with the other rspec gems.
+
+### 2.8.0.rc1 / 2011-11-06
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.7.0...v2.8.0.rc1)
+
+Enhancements
+
+* Eliminate Ruby warnings (Matijs van Zuijlen)
+
+### 2.7.0 / 2011-10-16
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.6.0...v2.7.0)
+
+Enhancements
+
+* Use `__send__` rather than `send` (alextk)
+* Add support for `any_instance.stub_chain` (Sidu Ponnappa)
+* Add support for `any_instance` argument matching based on `with` (Sidu
+  Ponnappa and Andy Lindeman)
+
+Changes
+
+* Check for `failure_message_for_should` or `failure_message` instead of
+  `description` to detect a matcher (Tibor Claassen)
+
+Bug fixes
+
+* pass a hash to `any_instance.stub`. (Justin Ko)
+* allow `to_ary` to be called without raising `NoMethodError` (Mikhail
+  Dieterle)
+* `any_instance` properly restores private methods (Sidu Ponnappa)
+
+### 2.6.0 / 2011-05-12
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.0)
+
+Enhancements
+
+* Add support for `any_instance.stub` and `any_instance.should_receive` (Sidu
+  Ponnappa and Andy Lindeman)
+
+Bug fixes
+
+* fix bug in which multiple chains with shared messages ending in hashes failed
+  to return the correct value
+
+### 2.5.0 / 2011-02-05
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0)
+
+Bug fixes
+
+* message expectation counts now work in combination with a stub (Damian
+  Nurzynski)
+* fix failure message when message received with incorrect args (Josep M.
+  Bach)
+
+### 2.4.0 / 2011-01-02
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.3.0...v2.4.0)
+
+No functional changes in this release, which was made to align with the
+rspec-core-2.4.0 release.
+
+### 2.3.0 / 2010-12-12
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.2.0...v2.3.0)
+
+Bug fixes
+
+* Fix our Marshal extension so that it does not interfere with objects that
+  have their own `@mock_proxy` instance variable. (Myron Marston)
+
+### 2.2.0 / 2010-11-28
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.1.0...v2.2.0)
+
+Enhancements
+
+* Added "rspec/mocks/standalone" for exploring the rspec-mocks in irb.
+
+Bug fix
+
+* Eliminate warning on splat args without parens (Gioele Barabucci)
+* Fix bug where `obj.should_receive(:foo).with(stub.as_null_object)` would pass
+  with a false positive.
+
+### 2.1.0 / 2010-11-07
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.1...v2.1.0)
+
+Bug fixes
+
+* Fix serialization of stubbed object (Josep M Bach)
+
+### 2.0.0 / 2010-10-10
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0)
+
+### 2.0.0.rc / 2010-10-05
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0.rc)
+
+Enhancements
+
+* support passing a block to an expectation block (Nicolas Braem)
+    * `obj.should_receive(:msg) {|&block| ... }`
+
+Bug fixes
+
+* Fix YAML serialization of stub (Myron Marston)
+* Fix rdoc rake task (Hans de Graaff)
+
+### 2.0.0.beta.22 / 2010-09-12
+
+[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.20...v2.0.0.beta.22)
+
+Bug fixes
+
+* fixed regression that broke `obj.stub_chain(:a, :b => :c)`
+* fixed regression that broke `obj.stub_chain(:a, :b) { :c }`
+* `respond_to?` always returns true when using `as_null_object`
diff --git a/rspec-mocks/DEV-README.md b/rspec-mocks/DEV-README.md
new file mode 100644
index 0000000..cbb78ab
--- /dev/null
+++ b/rspec-mocks/DEV-README.md
@@ -0,0 +1,28 @@
+## Set up the dev environment
+
+    git clone git://github.com/rspec/rspec-mocks.git
+    cd rspec-mocks
+    gem install bundler
+    bundle install
+
+Now you should be able to run any of:
+
+    rake
+    rake spec
+    rake cucumber
+
+Or, if you prefer to use the rspec and cucumber commands directly, you can either:
+
+    bundle exec rspec
+
+Or ...
+
+    bundle install --binstubs
+    bin/rspec
+
+## Customize the dev enviroment
+
+The Gemfile includes the gems you'll need to be able to run specs. If you want
+to customize your dev enviroment with additional tools like guard or
+ruby-debug, add any additional gem declarations to Gemfile-custom (see
+Gemfile-custom.sample for some examples).
diff --git a/rspec-mocks/Gemfile b/rspec-mocks/Gemfile
new file mode 100644
index 0000000..fcccdb8
--- /dev/null
+++ b/rspec-mocks/Gemfile
@@ -0,0 +1,30 @@
+source "https://rubygems.org"
+
+gemspec
+
+branch = File.read(File.expand_path("../maintenance-branch", __FILE__)).chomp
+%w[rspec rspec-core rspec-expectations rspec-support].each do |lib|
+  library_path = File.expand_path("../../#{lib}", __FILE__)
+  if File.exist?(library_path) && !ENV['USE_GIT_REPOS']
+    gem lib, :path => library_path
+  else
+    gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => branch
+  end
+end
+
+gem 'yard', '~> 0.8.7', :require => false
+gem 'rubocop', "~> 0.23.0", :platform => [:ruby_19, :ruby_20, :ruby_21]
+
+### deps for rdoc.info
+group :documentation do
+  gem 'redcarpet',     '2.1.1' unless RUBY_PLATFORM == 'java'
+  gem 'github-markup', '0.7.2'
+end
+
+gem 'simplecov', '~> 0.8'
+
+platforms :jruby do
+  gem "jruby-openssl"
+end
+
+eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
diff --git a/rspec-mocks/Gemfile-custom.sample b/rspec-mocks/Gemfile-custom.sample
new file mode 100644
index 0000000..a501767
--- /dev/null
+++ b/rspec-mocks/Gemfile-custom.sample
@@ -0,0 +1,19 @@
+group :development do
+  gem 'interactive_rspec'
+  gem 'relish', '~> 0.6.0'
+  gem 'guard-rspec', '~> 1.2.1'
+  gem 'growl', '1.0.3'
+  gem 'spork', '0.9.0'
+
+  platform :mri do
+    gem 'rb-fsevent', '~> 0.9.0'
+    gem 'ruby-prof', '~> 0.10.0'
+
+    case RUBY_VERSION
+    when /^1.8/
+      gem 'ruby-debug'
+    when /^1.9/
+      gem 'debugger'
+    end
+  end
+end
diff --git a/rspec-mocks/Guardfile b/rspec-mocks/Guardfile
new file mode 100644
index 0000000..eea6d3f
--- /dev/null
+++ b/rspec-mocks/Guardfile
@@ -0,0 +1,8 @@
+# A sample Guardfile
+# More info at http://github.com/guard/guard#readme
+
+guard 'rspec', :version => 2 do
+  watch(/^spec\/(.*)_spec.rb/)
+  watch(/^lib\/(.*)\.rb/)                              { "spec" }
+  watch(/^spec\/spec_helper.rb/)                       { "spec" }
+end
diff --git a/License.txt b/rspec-mocks/License.txt
similarity index 95%
copy from License.txt
copy to rspec-mocks/License.txt
index 02bc06c..91cfc94 100644
--- a/License.txt
+++ b/rspec-mocks/License.txt
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2009 Chad Humphries, David Chelimsky
+Copyright (c) 2012 David Chelimsky, Myron Marston
 Copyright (c) 2006 David Chelimsky, The RSpec Development Team
 Copyright (c) 2005 Steven Baker
 
diff --git a/rspec-mocks/README.md b/rspec-mocks/README.md
new file mode 100644
index 0000000..e9a5955
--- /dev/null
+++ b/rspec-mocks/README.md
@@ -0,0 +1,430 @@
+# RSpec Mocks [![Build Status](https://secure.travis-ci.org/rspec/rspec-mocks.svg?branch=master)](http://travis-ci.org/rspec/rspec-mocks) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks)
+rspec-mocks is a test-double framework for rspec with support for method stubs,
+fakes, and message expectations on generated test-doubles and real objects
+alike.
+
+## Install
+
+    gem install rspec       # for rspec-core, rspec-expectations, rspec-mocks
+    gem install rspec-mocks # for rspec-mocks only
+
+Want to run against the `master` branch? You'll need to include the dependent
+RSpec repos as well. Add the following to your `Gemfile`:
+
+```ruby
+%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
+  gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => 'master'
+end
+```
+
+## Test Doubles
+
+A test double is an object that stands in for another object in your system
+during a code example. Use the `double` method, passing in an optional identifier, to create one:
+
+```ruby
+book = double("book")
+```
+
+Most of the time you will want some confidence that your doubles resemble an
+existing object in your system. Verifying doubles are provided for this
+purpose. If the existing object is available, they will prevent you from adding
+stubs and expectations for methods that do not exist or that have an invalid
+number of parameters.
+
+```ruby
+book = instance_double("Book", :pages => 250)
+```
+
+Verifying doubles have some clever tricks to enable you to both test in
+isolation without your dependencies loaded while still being able to validate
+them against real objects. More detail is available in [their
+documentation](https://github.com/rspec/rspec-mocks/blob/master/features/verifying_doubles).
+
+Verifying doubles can also accept custom identifiers, just like double(), e.g.:
+
+```ruby
+books = []
+books << instance_double("Book", :rspec_book, :pages => 250)
+books << instance_double("Book", "(Untitled)", :pages => 5000)
+
+puts books.inspect # with names, it's clearer which were actually added
+```
+
+## Method Stubs
+
+A method stub is an implementation that returns a pre-determined value.  Method
+stubs can be declared on test doubles or real objects using the same syntax.
+rspec-mocks supports 3 forms for declaring method stubs:
+
+```ruby
+allow(book).to receive(:title) { "The RSpec Book" }
+allow(book).to receive(:title).and_return("The RSpec Book")
+allow(book).to receive_messages(
+    :title => "The RSpec Book",
+    :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends")
+```
+
+You can also use this shortcut, which creates a test double and declares a
+method stub in one statement:
+
+```ruby
+book = double("book", :title => "The RSpec Book")
+```
+
+The first argument is a name, which is used for documentation and appears in
+failure messages. If you don't care about the name, you can leave it out,
+making the combined instantiation/stub declaration very terse:
+
+```ruby
+double(:foo => 'bar')
+```
+
+This is particularly nice when providing a list of test doubles to a method
+that iterates through them:
+
+```ruby
+order.calculate_total_price(double(:price => 1.99), double(:price => 2.99))
+```
+
+## Consecutive return values
+
+When a stub might be invoked more than once, you can provide additional
+arguments to `and_return`.  The invocations cycle through the list. The last
+value is returned for any subsequent invocations:
+
+```ruby
+allow(die).to receive(:roll).and_return(1, 2, 3)
+die.roll # => 1
+die.roll # => 2
+die.roll # => 3
+die.roll # => 3
+die.roll # => 3
+```
+
+To return an array in a single invocation, declare an array:
+
+```ruby
+allow(team).to receive(:players).and_return([double(:name => "David")])
+```
+
+## Message Expectations
+
+A message expectation is an expectation that the test double will receive a
+message some time before the example ends. If the message is received, the
+expectation is satisfied. If not, the example fails.
+
+```ruby
+validator = double("validator")
+expect(validator).to receive(:validate) { "02134" }
+zipcode = Zipcode.new("02134", validator)
+zipcode.valid?
+```
+
+## Test Spies
+
+Verifies the given object received the expected message during the course of
+the test. For a message to be verified, the given object must be setup to spy
+on it, either by having it explicitly stubbed or by being a null object double
+(e.g. `double(...).as_null_object`). Convenience methods are provided to easily
+create null object doubles for this purpose:
+
+```ruby
+spy("invitation") # => same as `double("invitation").as_null_object`
+instance_spy("Invitation") # => same as `instance_double("Invitation").as_null_object`
+class_spy("Invitation") # => same as `class_double("Invitation").as_null_object`
+object_spy("Invitation") # => same as `object_double("Invitation").as_null_object`
+```
+
+Verifying messages received in this way implements the Test Spy pattern.
+
+```ruby
+invitation = spy('invitation')
+
+user.accept_invitation(invitation)
+
+expect(invitation).to have_received(:accept)
+
+# You can also use other common message expectations. For example:
+expect(invitation).to have_received(:accept).with(mailer)
+expect(invitation).to have_received(:accept).twice
+expect(invitation).to_not have_received(:accept).with(mailer)
+
+# One can specify a return value on the spy the same way one would a double.
+invitation = spy('invitation', :accept => true)
+expect(invitation).to have_received(:accept).with(mailer)
+expect(invitation.accept).to eq(true)
+```
+
+Note that `have_received(...).with(...)` is unable to work properly when
+passed arguments are mutated after the spy records the received message.
+For example, this does not work properly:
+
+```ruby
+greeter = spy("greeter")
+
+message = "Hello"
+greeter.greet_with(message)
+message << ", World"
+
+expect(greeter).to have_received(:greet_with).with("Hello")
+```
+
+## Nomenclature
+
+### Mock Objects and Test Stubs
+
+The names Mock Object and Test Stub suggest specialized Test Doubles.  i.e.
+a Test Stub is a Test Double that only supports method stubs, and a Mock
+Object is a Test Double that supports message expectations and method
+stubs.
+
+There is a lot of overlapping nomenclature here, and there are many
+variations of these patterns (fakes, spies, etc). Keep in mind that most of
+the time we're talking about method-level concepts that are variations of
+method stubs and message expectations, and we're applying to them to _one_
+generic kind of object: a Test Double.
+
+### Test-Specific Extension
+
+a.k.a. Partial Double, a Test-Specific Extension is an extension of a
+real object in a system that is instrumented with test-double like
+behaviour in the context of a test. This technique is very common in Ruby
+because we often see class objects acting as global namespaces for methods.
+For example, in Rails:
+
+```ruby
+person = double("person")
+allow(Person).to receive(:find) { person }
+```
+
+In this case we're instrumenting Person to return the person object we've
+defined whenever it receives the `find` message. We can also set a message
+expectation so that the example fails if `find` is not called:
+
+```ruby
+person = double("person")
+expect(Person).to receive(:find) { person }
+```
+
+RSpec replaces the method we're stubbing or mocking with its own
+test-double-like method. At the end of the example, RSpec verifies any message
+expectations, and then restores the original methods.
+
+## Expecting Arguments
+
+```ruby
+expect(double).to receive(:msg).with(*args)
+expect(double).to_not receive(:msg).with(*args)
+```
+
+You can set multiple expectations for the same message if you need to:
+
+```ruby
+expect(double).to receive(:msg).with("A", 1, 3)
+expect(double).to receive(:msg).with("B", 2, 4)
+```
+
+## Argument Matchers
+
+Arguments that are passed to `with` are compared with actual arguments
+received using ==. In cases in which you want to specify things about the
+arguments rather than the arguments themselves, you can use any of the
+matchers that ship with rspec-expectations. They don't all make syntactic
+sense (they were primarily designed for use with RSpec::Expectations), but
+you are free to create your own custom RSpec::Matchers.
+
+rspec-mocks also adds some keyword Symbols that you can use to
+specify certain kinds of arguments:
+
+```ruby
+expect(double).to receive(:msg).with(no_args)
+expect(double).to receive(:msg).with(any_args)
+expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere
+expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric
+expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false
+expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
+expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
+expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div
+expect(double).to receive(:msg).with(hash_including(:a => 5)) # first arg is a hash with a: 5 as one of the key-values
+expect(double).to receive(:msg).with(array_including(5)) # first arg is an array with 5 as one of the key-values
+expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a hash without a: 5 as one of the key-values
+```
+
+## Receive Counts
+
+```ruby
+expect(double).to receive(:msg).once
+expect(double).to receive(:msg).twice
+expect(double).to receive(:msg).exactly(n).times
+expect(double).to receive(:msg).at_least(:once)
+expect(double).to receive(:msg).at_least(:twice)
+expect(double).to receive(:msg).at_least(n).times
+expect(double).to receive(:msg).at_most(:once)
+expect(double).to receive(:msg).at_most(:twice)
+expect(double).to receive(:msg).at_most(n).times
+```
+
+## Ordering
+
+```ruby
+expect(double).to receive(:msg).ordered
+expect(double).to receive(:other_msg).ordered
+  # This will fail if the messages are received out of order
+```
+
+This can include the same message with different arguments:
+
+```ruby
+expect(double).to receive(:msg).with("A", 1, 3).ordered
+expect(double).to receive(:msg).with("B", 2, 4).ordered
+```
+
+## Setting Responses
+
+Whether you are setting a message expectation or a method stub, you can
+tell the object precisely how to respond. The most generic way is to pass
+a block to `receive`:
+
+```ruby
+expect(double).to receive(:msg) { value }
+```
+
+When the double receives the `msg` message, it evaluates the block and returns
+the result.
+
+```ruby
+expect(double).to receive(:msg).and_return(value)
+expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3)
+  # returns value1 the first time, value2 the second, etc
+expect(double).to receive(:msg).and_raise(error)
+  # error can be an instantiated object or a class
+  # if it is a class, it must be instantiable with no args
+expect(double).to receive(:msg).and_throw(:msg)
+expect(double).to receive(:msg).and_yield(values, to, yield)
+expect(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time)
+  # for methods that yield to a block multiple times
+```
+
+Any of these responses can be applied to a stub as well
+
+```ruby
+allow(double).to receive(:msg).and_return(value)
+allow(double).to receive(:msg).and_return(value1, value2, value3)
+allow(double).to receive(:msg).and_raise(error)
+allow(double).to receive(:msg).and_throw(:msg)
+allow(double).to receive(:msg).and_yield(values, to, yield)
+allow(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time)
+```
+
+## Arbitrary Handling
+
+Once in a while you'll find that the available expectations don't solve the
+particular problem you are trying to solve. Imagine that you expect the message
+to come with an Array argument that has a specific length, but you don't care
+what is in it. You could do this:
+
+```ruby
+expect(double).to receive(:msg) do |arg|
+  expect(arg.size).to eq 7
+end
+```
+
+If the method being stubbed itself takes a block, and you need to yield to it
+in some special way, you can use this:
+
+```ruby
+expect(double).to receive(:msg) do |&arg|
+  begin
+    arg.call
+  ensure
+    # cleanup
+  end
+end
+```
+
+## Delegating to the Original Implementation
+
+When working with a partial mock object, you may occasionally
+want to set a message expecation without interfering with how
+the object responds to the message. You can use `and_call_original`
+to achieve this:
+
+```ruby
+expect(Person).to receive(:find).and_call_original
+Person.find # => executes the original find method and returns the result
+```
+
+## Combining Expectation Details
+
+Combining the message name with specific arguments, receive counts and responses
+you can get quite a bit of detail in your expectations:
+
+```ruby
+expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError)
+```
+
+While this is a good thing when you really need it, you probably don't really
+need it! Take care to specify only the things that matter to the behavior of
+your code.
+
+## Stubbing and Hiding Constants
+
+See the [mutating constants
+README](https://github.com/rspec/rspec-mocks/blob/master/features/mutating_constants/README.md)
+for info on this feature.
+
+## Use `before(:example)`, not `before(:context)`
+
+Stubs in `before(:context)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:context)` would work in the first example that happens to run in that group, but not for any others.
+
+Instead of `before(:context)`, use `before(:example)`.
+
+## Settings mocks or stubs on any instance of a class
+
+rspec-mocks provides two methods, `allow_any_instance_of` and
+`expect_any_instance_of`, that will allow you to stub or mock any instance
+of a class. They are used in place of `allow` or `expect`:
+
+```ruby
+allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
+expect_any_instance_of(Widget).to receive(:name).and_return("Wobble")
+```
+
+These methods add the appropriate stub or expectation to all instances of
+`Widget`.
+
+This feature is sometimes useful when working with legacy code, though in
+general we discourage its use for a number of reasons:
+
+* The `rspec-mocks` API is designed for individual object instances, but this
+  feature operates on entire classes of objects. As a result there are some
+  semantically confusing edge cases. For example in
+  `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear
+  whether each specific instance is expected to receive `name` twice, or if two
+  receives total are expected. (It's the former.)
+* Using this feature is often a design smell. It may be
+  that your test is trying to do too much or that the object under test is too
+  complex.
+* It is the most complicated feature of `rspec-mocks`, and has historically
+  received the most bug reports. (None of the core team actively use it,
+  which doesn't help.)
+
+
+## Further Reading
+
+There are many different viewpoints about the meaning of mocks and stubs. If
+you are interested in learning more, here is some recommended reading:
+
+* Mock Objects: http://www.mockobjects.com/
+* Endo-Testing: http://stalatest.googlecode.com/svn/trunk/Literatur/mockobjects.pdf
+* Mock Roles, Not Objects: http://jmock.org/oopsla2004.pdf
+* Test Double: http://www.martinfowler.com/bliki/TestDouble.html
+* Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html
+* Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html
+
+## Also see
+
+* [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
+* [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
+* [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations)
diff --git a/rspec-mocks/Rakefile b/rspec-mocks/Rakefile
new file mode 100644
index 0000000..492f66f
--- /dev/null
+++ b/rspec-mocks/Rakefile
@@ -0,0 +1,72 @@
+require 'bundler'
+Bundler.setup
+Bundler::GemHelper.install_tasks
+
+require 'rake'
+require 'rspec/core/rake_task'
+require 'rspec/mocks/version'
+require 'cucumber/rake/task'
+
+desc "Run all examples"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.ruby_opts = %w[-w]
+  t.rspec_opts = %w[--color]
+end
+
+Cucumber::Rake::Task.new(:cucumber)
+
+task :clobber do
+  rm_rf 'pkg'
+  rm_rf 'tmp'
+  rm_rf 'coverage'
+  rm_rf '.yardoc'
+  rm_rf 'doc'
+end
+
+namespace :clobber do
+  desc "remove generated rbc files"
+  task :rbc do
+    Dir['**/*.rbc'].each {|f| File.delete(f)}
+  end
+end
+
+with_changelog_in_features = lambda do |&block|
+  begin
+    sh "cp Changelog.md features/"
+    block.call
+  ensure
+    sh "rm features/Changelog.md"
+  end
+end
+
+desc "Push docs/cukes to relishapp using the relish-client-gem"
+task :relish, :version do |t, args|
+  raise "rake relish[VERSION]" unless args[:version]
+
+  with_changelog_in_features.call do
+    if `relish versions rspec/rspec-mocks`.split.map(&:strip).include? args[:version]
+      puts "Version #{args[:version]} already exists"
+    else
+      sh "relish versions:add rspec/rspec-mocks:#{args[:version]}"
+    end
+    sh "relish push rspec/rspec-mocks:#{args[:version]}"
+  end
+end
+
+desc "Push to relish staging environment"
+task :relish_staging do
+  with_changelog_in_features.call do
+    sh "relish push rspec-staging/rspec-mocks"
+  end
+end
+
+task :default => [:spec, :cucumber]
+
+task :verify_private_key_present do
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  unless File.exist?(private_key)
+    raise "Your private key is not present. This gem should not be built without that."
+  end
+end
+
+task :build => :verify_private_key_present
diff --git a/rspec-mocks/appveyor.yml b/rspec-mocks/appveyor.yml
new file mode 100644
index 0000000..9e4f457
--- /dev/null
+++ b/rspec-mocks/appveyor.yml
@@ -0,0 +1,34 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+version: "{build}"
+
+# This will build all PRs targetting matching branches.
+# Without this, each PR builds twice -- once for the PR branch HEAD,
+# and once for the merge commit that github creates for each mergable PR.
+branches:
+  only:
+    - master
+    - /.*-maintenance$/
+
+# Disable normal Windows builds in favor of our test script.
+build: off
+
+install:
+  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
+  - ruby --version
+  - gem --version
+  # We lock to 1.7.7 to avoid warnings from 1.7.8
+  - gem install bundler -v=1.7.7
+  - bundler --version
+  - bundle install
+  - cinst ansicon
+
+test_script:
+  - bundle exec rspec
+
+environment:
+  matrix:
+    # ruby_version: '20' doesn't work for some reason
+    - ruby_version: '193'
+    - ruby_version: '21'
diff --git a/rspec-mocks/benchmarks/boot_time.sh b/rspec-mocks/benchmarks/boot_time.sh
new file mode 100755
index 0000000..39d12d2
--- /dev/null
+++ b/rspec-mocks/benchmarks/boot_time.sh
@@ -0,0 +1,31 @@
+time (for i in {1..100}; do ruby -Ilib:../rspec-support/lib -rrspec/mocks -e ""; done)
+
+# 3 runs before our autoload changes
+# real  0m4.497s
+# user  0m3.662s
+# sys 0m0.677s
+#
+# real  0m4.472s
+# user  0m3.644s
+# sys 0m0.671s
+#
+# real  0m4.465s
+# user  0m3.640s
+# sys 0m0.668s
+
+# 3 runs after our autoload changes:
+#
+# real  0m4.038s
+# user  0m3.274s
+# sys 0m0.609s
+#
+# real  0m4.038s
+# user  0m3.274s
+# sys 0m0.609s
+#
+# real  0m4.038s
+# user  0m3.274s
+# sys 0m0.609s
+
+# It's modest, but that's about a 10% improvement: an average
+# of about 40ms to load rather than 45 ms to load.
diff --git a/rspec-mocks/benchmarks/double_creation.rb b/rspec-mocks/benchmarks/double_creation.rb
new file mode 100644
index 0000000..6549374
--- /dev/null
+++ b/rspec-mocks/benchmarks/double_creation.rb
@@ -0,0 +1,66 @@
+$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
+
+require 'benchmark'
+require 'rspec/mocks'
+
+n = 1000
+
+puts "#{n} times - ruby #{RUBY_VERSION}"
+puts
+
+Benchmark.bm do |bm|
+  RSpec::Mocks.setup(self)
+
+  (0..9).each do |m|
+    attrs = m.times.inject({}) {|h, x|
+      h["method_#{x}"] = x
+      h
+    }
+
+    bm.report("#{m} attrs") do
+      n.times do
+        double(attrs)
+      end
+    end
+  end
+end
+# $ export OLD_REV=d483e0a893d97c7b8e612e878a9f3562a210df9f
+# $ git checkout $OLD_REV
+# $ ruby benchmarks/double_creation.rb
+# 1000 times - ruby 2.0.0
+#
+#           user     system      total        real
+#    0 attrs  0.010000   0.000000   0.010000 (  0.003686)
+#    1 attrs  0.110000   0.000000   0.110000 (  0.143132)
+#    2 attrs  0.230000   0.010000   0.240000 (  0.311358)
+#    3 attrs  0.400000   0.020000   0.420000 (  0.465994)
+#    4 attrs  0.570000   0.010000   0.580000 (  0.597902)
+#    5 attrs  0.920000   0.010000   0.930000 (  1.060219)
+#    6 attrs  1.350000   0.020000   1.370000 (  1.388386)
+#    7 attrs  1.770000   0.030000   1.800000 (  1.805518)
+#    8 attrs  2.620000   0.030000   2.650000 (  2.681484)
+#    9 attrs  3.320000   0.030000   3.350000 (  3.380757)
+#
+# $ export NEW_REV=13e9d11542a6b60c5dc7ffa4527c98bb255d0a1f
+# $ git checkout $NEW_REV
+# $ ruby benchmarks/double_creation.rb
+# 1000 times - ruby 2.0.0
+#
+#             user     system      total        real
+#    0 attrs  0.010000   0.000000   0.010000 (  0.001544)
+#    1 attrs  0.040000   0.000000   0.040000 (  0.043522)
+#    2 attrs  0.060000   0.000000   0.060000 (  0.081742)
+#    3 attrs  0.090000   0.010000   0.100000 (  0.104526)
+#    4 attrs  0.120000   0.010000   0.130000 (  0.132472)
+#    5 attrs  0.150000   0.010000   0.160000 (  0.162368)
+#    6 attrs  0.190000   0.010000   0.200000 (  0.204610)
+#    7 attrs  0.220000   0.010000   0.230000 (  0.237983)
+#    8 attrs  0.260000   0.010000   0.270000 (  0.281562)
+#    9 attrs  0.310000   0.020000   0.330000 (  0.334489)
+#
+# $ git log $OLD_REV..$NEW_REV --oneline
+# 13e9d11 Remove unused arguments from simple stub interface.
+# 009a697 Extract CallerFilter class to unify caller manipulation.
+# 46c1eb0 Introduce "simple" stub as an optimization over using a normal stub.
+# 4a04b3e Extract constant ArgumentListMatcher::MATCH_ALL.
+# 860d591 Speed up double creation with multiple attributes by caching caller.
diff --git a/rspec-mocks/benchmarks/each_value_v_values_each.rb b/rspec-mocks/benchmarks/each_value_v_values_each.rb
new file mode 100644
index 0000000..cff19fd
--- /dev/null
+++ b/rspec-mocks/benchmarks/each_value_v_values_each.rb
@@ -0,0 +1,58 @@
+require 'benchmark'
+
+n = 10000
+
+m = 1.upto(1000).reduce({}) {|m, i| m[i] = i; m}
+
+Benchmark.benchmark do |bm|
+  puts "#{n} times - ruby #{RUBY_VERSION}"
+
+  puts
+  puts "each_value"
+
+  3.times do
+    bm.report do
+      n.times do
+        m.each_value {|v|}
+      end
+    end
+  end
+
+  puts
+  puts "values.each"
+
+  3.times do
+    bm.report do
+      n.times do
+        m.values.each{|v|}
+      end
+    end
+  end
+end
+
+# $ ruby benchmarks/values_each_v_each_value.rb
+#  10000 times - ruby 1.9.3
+#
+# each_value
+#    0.720000   0.000000   0.720000 (  0.720237)
+#    0.720000   0.000000   0.720000 (  0.724956)
+#    0.730000   0.000000   0.730000 (  0.730352)
+#
+# values.each
+#    0.910000   0.000000   0.910000 (  0.917496)
+#    0.910000   0.010000   0.920000 (  0.909319)
+#    0.910000   0.000000   0.910000 (  0.911225)
+
+
+# $ ruby benchmarks/values_each_v_each_value.rb
+# 10000 times - ruby 2.0.0
+#
+# each_value
+#    0.730000   0.000000   0.730000 (  0.738443)
+#    0.720000   0.000000   0.720000 (  0.720183)
+#    0.720000   0.000000   0.720000 (  0.720866)
+#
+# values.each
+#    0.940000   0.000000   0.940000 (  0.942597)
+#    0.960000   0.010000   0.970000 (  0.959248)
+#    0.960000   0.000000   0.960000 (  0.959099)
diff --git a/rspec-mocks/benchmarks/find_original_method_early.rb b/rspec-mocks/benchmarks/find_original_method_early.rb
new file mode 100644
index 0000000..875ea9d
--- /dev/null
+++ b/rspec-mocks/benchmarks/find_original_method_early.rb
@@ -0,0 +1,64 @@
+$LOAD_PATH.unshift "./lib"
+require 'rspec/mocks'
+require "rspec/mocks/standalone"
+
+=begin
+This benchmark script is for troubleshooting the performance of
+#264. To use it, you have to edit the code in #264 a bit:
+wrap the call in `MethodDouble#initialize` to `find_original_method`
+in a conditional like `if $find_original`.
+
+That allows the code below to compare the perf of stubbing a method
+with the original method being found vs. not.
+=end
+
+require 'benchmark'
+
+n = 10000
+
+Foo = Class.new(Object) do
+  n.times do |i|
+    define_method "meth_#{i}" do
+    end
+  end
+end
+
+Benchmark.bmbm do |bm|
+  puts "#{n} times - ruby #{RUBY_VERSION}"
+
+  perform_report = lambda do |label, find_original, &create_object|
+    dbl = create_object.call
+    $find_original = find_original
+
+    bm.report(label) do
+      n.times do |i|
+        dbl.stub("meth_#{i}")
+      end
+    end
+
+    RSpec::Mocks.space.reset_all
+  end
+
+  perform_report.call("Find original - partial mock", true) { Foo.new }
+  perform_report.call("Don't find original - partial mock", false) { Foo.new }
+  perform_report.call("Find original - test double", true) { double }
+  perform_report.call("Don't find original - test double", false) { double }
+end
+
+=begin
+
+10000 times - ruby 1.9.3
+Rehearsal ----------------------------------------------------------------------
+Don't find original - partial mock   1.050000   0.020000   1.070000 (  1.068561)
+Don't find original - test double    1.190000   0.010000   1.200000 (  1.199815)
+Find original - partial mock         1.270000   0.010000   1.280000 (  1.282944)
+Find original - test double          1.320000   0.020000   1.340000 (  1.336136)
+------------------------------------------------------------- total: 4.890000sec
+
+                                         user     system      total        real
+Don't find original - partial mock   0.990000   0.000000   0.990000 (  1.000959)
+Don't find original - test double    0.930000   0.010000   0.940000 (  0.931871)
+Find original - partial mock         1.040000   0.000000   1.040000 (  1.046354)
+Find original - test double          0.980000   0.010000   0.990000 (  0.983577)
+
+=end
diff --git a/rspec-mocks/benchmarks/method_defined_at_any_visibility.rb b/rspec-mocks/benchmarks/method_defined_at_any_visibility.rb
new file mode 100644
index 0000000..d538c20
--- /dev/null
+++ b/rspec-mocks/benchmarks/method_defined_at_any_visibility.rb
@@ -0,0 +1,101 @@
+require 'benchmark'
+
+n = 1_000_000
+
+Foo = Class.new do
+  1.upto(n) do |i|
+    define_method(:"public_method_#{i}") { }
+    define_method(:"protected_method_#{i}") { }
+    protected :"protected_method_#{i}"
+    define_method(:"private_method_#{i}") { }
+    private :"protected_method_#{i}"
+  end
+end
+
+Benchmark.benchmark do |bm|
+  puts "#{n} times - ruby #{RUBY_VERSION}"
+
+  puts
+  puts "using method_defined? and private_method_defined?"
+  puts
+
+  [:public, :protected, :private, :undefined].each do |vis|
+    puts "  - #{vis} methods"
+
+    3.times do
+      GC.start
+
+      bm.report do
+        n.times do |i|
+          name = :"#{vis}_method_#{i}"
+          Foo.method_defined?(name) || Foo.private_method_defined?(name)
+        end
+      end
+    end
+  end
+
+  puts
+  puts "using public_method_defined?, protected_method_defined? and private_method_defined?"
+  puts
+
+  [:public, :protected, :private, :undefined].each do |vis|
+    puts "  - #{vis} methods"
+
+    3.times do
+      GC.start
+
+      bm.report do
+        n.times do |i|
+          name = :"#{vis}_method_#{i}"
+          Foo.public_method_defined?(name) ||
+          Foo.protected_method_defined?(name)
+          Foo.private_method_defined?(name)
+        end
+      end
+    end
+  end
+end
+
+=begin
+
+1000000 times - ruby 2.0.0
+
+using method_defined? and private_method_defined?
+
+  - public methods
+   1.410000   0.040000   1.450000 (  1.462588)
+   1.380000   0.000000   1.380000 (  1.372015)
+   1.370000   0.000000   1.370000 (  1.372362)
+  - protected methods
+   1.410000   0.000000   1.410000 (  1.402750)
+   1.440000   0.000000   1.440000 (  1.442719)
+   1.460000   0.010000   1.470000 (  1.464763)
+  - private methods
+   1.390000   0.000000   1.390000 (  1.393956)
+   1.340000   0.000000   1.340000 (  1.349340)
+   1.360000   0.000000   1.360000 (  1.361910)
+  - undefined methods
+   3.260000   0.050000   3.310000 (  3.316372)
+   1.260000   0.010000   1.270000 (  1.266557)
+   1.250000   0.000000   1.250000 (  1.248734)
+
+using public_method_defined?, protected_method_defined? and private_method_defined?
+
+  - public methods
+   1.550000   0.000000   1.550000 (  1.550655)
+   1.540000   0.010000   1.550000 (  1.543906)
+   1.540000   0.000000   1.540000 (  1.538267)
+  - protected methods
+   1.590000   0.000000   1.590000 (  1.598310)
+   1.600000   0.000000   1.600000 (  1.595205)
+   1.600000   0.000000   1.600000 (  1.604186)
+  - private methods
+   1.530000   0.000000   1.530000 (  1.530080)
+   1.560000   0.000000   1.560000 (  1.562656)
+   1.560000   0.000000   1.560000 (  1.569161)
+  - undefined methods
+   1.300000   0.000000   1.300000 (  1.298066)
+   1.310000   0.000000   1.310000 (  1.310737)
+   1.290000   0.000000   1.290000 (  1.288307)
+
+=end
diff --git a/rspec-mocks/benchmarks/thread_safety.rb b/rspec-mocks/benchmarks/thread_safety.rb
new file mode 100644
index 0000000..6ab2427
--- /dev/null
+++ b/rspec-mocks/benchmarks/thread_safety.rb
@@ -0,0 +1,24 @@
+$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
+
+require 'benchmark'
+require 'rspec/mocks'
+
+Benchmark.bm do |bm|
+  bm.report("fetching a proxy") do
+    RSpec::Mocks.with_temporary_scope do
+      o = Object.new
+      100000.times {
+        RSpec::Mocks.space.proxy_for(o)
+      }
+    end
+  end
+end
+
+# Without synchronize (not thread-safe):
+#
+#       user     system      total        real
+# fetching a proxy  0.120000   0.000000   0.120000 (  0.141333)
+#
+# With synchronize (thread-safe):
+#       user     system      total        real
+# fetching a proxy  0.180000   0.000000   0.180000 (  0.189553)
diff --git a/rspec-mocks/benchmarks/transfer_nested_constants.rb b/rspec-mocks/benchmarks/transfer_nested_constants.rb
new file mode 100644
index 0000000..e46d42d
--- /dev/null
+++ b/rspec-mocks/benchmarks/transfer_nested_constants.rb
@@ -0,0 +1,77 @@
+$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
+
+require 'benchmark'
+require 'rspec/mocks'
+
+N = ENV.fetch('N', 10000).to_i
+M = ENV.fetch('M', 5).to_i
+
+puts "#{N} times, #{M} constants - ruby #{RUBY_VERSION}"
+puts
+
+class A
+  M.times do |x|
+    const_set("C#{x}", Object.new)
+  end
+end
+
+Benchmark.bm(20) do |bm|
+  RSpec::Mocks.setup(self)
+
+  bm.report("with constants") do
+    N.times do
+      class_double('A').as_stubbed_const(:transfer_nested_constants => true)
+    end
+  end
+
+  bm.report("without constants") do
+    N.times do
+      class_double('A').as_stubbed_const(:transfer_nested_constants => false)
+    end
+  end
+end
+
+# > for n in 1 10000; do for m in 0 5 100; do echo; \
+#     env N=$n M=$m ruby benchmarks/transfer_nested_constants.rb; \
+#   echo; done; done
+#
+# 1 times, 0 constants - ruby 2.0.0
+#
+#                            user     system      total        real
+# with constants         0.000000   0.000000   0.000000 (  0.000180)
+# without constants      0.000000   0.000000   0.000000 (  0.000071)
+#
+#
+# 1 times, 5 constants - ruby 2.0.0
+#
+#                            user     system      total        real
+# with constants         0.000000   0.000000   0.000000 (  0.000197)
+# without constants      0.000000   0.000000   0.000000 (  0.000123)
+#
+#
+# 1 times, 100 constants - ruby 2.0.0
+#
+#                            user     system      total        real
+# with constants         0.000000   0.000000   0.000000 (  0.000433)
+# without constants      0.000000   0.000000   0.000000 (  0.000115)
+#
+#
+# 10000 times, 0 constants - ruby 2.0.0
+#
+#                            user     system      total        real
+# with constants         0.900000   0.020000   0.920000 (  0.935583)
+# without constants      0.660000   0.010000   0.670000 (  0.680178)
+#
+#
+# 10000 times, 5 constants - ruby 2.0.0
+#
+#                            user     system      total        real
+# with constants         1.080000   0.020000   1.100000 (  1.114722)
+# without constants      0.720000   0.020000   0.740000 (  0.741976)
+#
+#
+# 10000 times, 100 constants - ruby 2.0.0
+#
+#                            user     system      total        real
+# with constants         3.870000   0.110000   3.980000 (  4.000176)
+# without constants      0.930000   0.010000   0.940000 (  0.947197)
diff --git a/rspec-mocks/cucumber.yml b/rspec-mocks/cucumber.yml
new file mode 100644
index 0000000..219fb27
--- /dev/null
+++ b/rspec-mocks/cucumber.yml
@@ -0,0 +1,2 @@
+default: --require features --tags ~@wip features --format progress
+wip: --require features --tags @wip:3 --wip features
diff --git a/rspec-mocks/features/.nav b/rspec-mocks/features/.nav
new file mode 100644
index 0000000..77f4a4a
--- /dev/null
+++ b/rspec-mocks/features/.nav
@@ -0,0 +1,43 @@
+- basics:
+  - test_doubles.feature
+  - allowing_messages.feature
+  - expecting_messages.feature
+  - partial_test_doubles.feature
+  - null_object_doubles.feature
+  - spies.feature
+  - scope.feature
+- verifying_doubles:
+  - instance_doubles.feature
+  - class_doubles.feature
+  - object_doubles.feature
+  - dynamic_classes.feature
+  - partial_doubles.feature
+- configuring_responses:
+  - returning_a_value.feature
+  - raising_an_error.feature
+  - throwing.feature
+  - yielding.feature
+  - calling_the_original_implementation.feature
+  - block_implementation.feature
+- setting_constraints:
+  - matching_arguments.feature
+  - receive_counts.feature
+  - message_order.feature
+- mutating_constants:
+  - stub_defined_constant.feature
+  - stub_undefined_constant.feature
+  - hide_defined_constant.feature
+  - hide_undefined_constant.feature
+- working_with_legacy_code:
+  - any_instance.feature
+  - message_chains.feature
+- old_syntax:
+  - stub.feature
+  - should_receive.feature
+  - any_instance.feature
+  - stub_chain.feature
+  - unstub.feature
+- outside_rspec:
+  - minitest.feature
+  - standalone.feature
+- Changelog
diff --git a/rspec-mocks/features/README.md b/rspec-mocks/features/README.md
new file mode 100644
index 0000000..0d988df
--- /dev/null
+++ b/rspec-mocks/features/README.md
@@ -0,0 +1,76 @@
+rspec-mocks helps to control the context in a code example by letting you set known return
+values, fake implementations of methods, and even set expectations that specific messages
+are received by an object.
+
+You can do these three things on test doubles that rspec-mocks creates for you on the fly, or
+you can do them on objects that are part of your system.
+
+## Messages and Methods
+
+_Message_ and _method_ are metaphors that we use somewhat interchangeably, but they are
+subtly different.  In Object Oriented Programming, objects communicate by sending
+_messages_ to one another. When an object receives a message, it invokes a _method_ with the
+same name as the message.
+
+## Test Doubles
+
+A test double is an object that stands in for another object in your system during a code
+example. Use the `double` method, passing in an optional identifier, to create one:
+
+```ruby
+book = double("book")
+```
+
+Most of the time you will want some confidence that your doubles resemble an existing
+object in your system. Verifying doubles are provided for this purpose. If the existing object
+is available, they will prevent you from adding stubs and expectations for methods that do
+not exist or that have invalid arguments.
+
+```ruby
+book = instance_double("Book", :pages => 250)
+```
+
+[Verifying doubles](./docs/verifying-doubles) have some clever tricks to enable you to both test in isolation without your
+dependencies loaded while still being able to validate them against real objects.
+
+## Method Stubs
+
+A method stub is an instruction to an object (real or test double) to return a
+known value in response to a message:
+
+```ruby
+allow(die).to receive(:roll) { 3 }
+```
+
+This tells the `die` object to return the value `3` when it receives the `roll` message.
+
+## Message Expectations
+
+A message expectation is an expectation that an object should receive a specific message
+during the course of a code example:
+
+```ruby
+describe Account do
+  context "when closed" do
+    it "logs an 'account closed' message" do
+      logger = double()
+      account = Account.new
+      account.logger = logger
+
+      expect(logger).to receive(:account_closed).with(account)
+
+      account.close
+    end
+  end
+end
+```
+
+This example specifies that the `account` object sends the `logger` the `account_closed`
+message (with itself as an argument) when it receives the `close` message.
+
+## Issues
+
+The documentation for rspec-mocks is a work in progress. We'll be adding Cucumber
+features over time, and clarifying existing ones. If you have specific features you'd like to see
+added, find the existing documentation incomplete or confusing, or, better yet, wish to write
+a missing Cucumber feature yourself, please [submit an issue](http://github.com/rspec/rspec-mocks/issues) or a [pull request](http://github.com/rspec/rspec-mocks).
diff --git a/rspec-mocks/features/basics/allowing_messages.feature b/rspec-mocks/features/basics/allowing_messages.feature
new file mode 100644
index 0000000..d801f25
--- /dev/null
+++ b/rspec-mocks/features/basics/allowing_messages.feature
@@ -0,0 +1,35 @@
+Feature: Allowing messages
+
+  [Test doubles](./test-doubles) are "strict" by default -- messages that have not been specifically
+  allowed or expected will trigger an error. Use `allow(...).to receive(...)` to configure
+  which messages are the double is allowed to receive. You can also use `allow(...).to
+  receive_messages(...)` to configure allowed messages (and return values) in bulk.
+
+  Scenario: Allowed messages return nil by default
+    Given a file named "allow_message_spec.rb" with:
+      """ruby
+      RSpec.describe "allow" do
+        it "returns nil from allowed messages" do
+          dbl = double("Some Collaborator")
+          allow(dbl).to receive(:foo)
+          expect(dbl.foo).to be_nil
+        end
+      end
+      """
+     When I run `rspec allow_message_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Messages can be allowed in bulk using `receive_messages`
+    Given a file named "receive_messages_spec.rb" with:
+      """ruby
+      RSpec.describe "receive_messages" do
+        it "configures return values for the provided messages" do
+          dbl = double("Some Collaborator")
+          allow(dbl).to receive_messages(:foo => 2, :bar => 3)
+          expect(dbl.foo).to eq(2)
+          expect(dbl.bar).to eq(3)
+        end
+      end
+      """
+     When I run `rspec receive_messages_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/basics/expecting_messages.feature b/rspec-mocks/features/basics/expecting_messages.feature
new file mode 100644
index 0000000..e885f95
--- /dev/null
+++ b/rspec-mocks/features/basics/expecting_messages.feature
@@ -0,0 +1,73 @@
+Feature: Expecting messages
+
+  Use `expect(...).to receive(...)` to expect a message on a [test double](./test-doubles). Unfulfilled
+  message expectations trigger failures when the example completes. You can also use
+  `expect(...).not_to receive(...)` to set a negative message expectation.
+
+  Scenario: Failing positive message expectation
+    Given a file named "unfulfilled_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "An unfulfilled positive message expectation" do
+        it "triggers a failure" do
+          dbl = double("Some Collaborator")
+          expect(dbl).to receive(:foo)
+        end
+      end
+      """
+     When I run `rspec unfulfilled_message_expectation_spec.rb`
+     Then it should fail with:
+      """
+        1) An unfulfilled positive message expectation triggers a failure
+           Failure/Error: expect(dbl).to receive(:foo)
+             (Double "Some Collaborator").foo(*(any args))
+                 expected: 1 time with any arguments
+                 received: 0 times with any arguments
+      """
+
+  Scenario: Passing positive message expectation
+    Given a file named "fulfilled_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "A fulfilled positive message expectation" do
+        it "passes" do
+          dbl = double("Some Collaborator")
+          expect(dbl).to receive(:foo)
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec fulfilled_message_expectation_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Failing negative message expectation
+    Given a file named "negative_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "A negative message expectation" do
+        it "fails when the message is received" do
+          dbl = double("Some Collaborator").as_null_object
+          expect(dbl).not_to receive(:foo)
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec negative_message_expectation_spec.rb`
+     Then it should fail with:
+      """
+        1) A negative message expectation fails when the message is received
+           Failure/Error: dbl.foo
+             (Double "Some Collaborator").foo(no args)
+                 expected: 0 times with any arguments
+                 received: 1 time
+      """
+
+  Scenario: Passing negative message expectation
+    Given a file named "negative_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "A negative message expectation" do
+        it "passes if the message is never received" do
+          dbl = double("Some Collaborator").as_null_object
+          expect(dbl).not_to receive(:foo)
+        end
+      end
+      """
+     When I run `rspec negative_message_expectation_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/basics/null_object_doubles.feature b/rspec-mocks/features/basics/null_object_doubles.feature
new file mode 100644
index 0000000..b2b9953
--- /dev/null
+++ b/rspec-mocks/features/basics/null_object_doubles.feature
@@ -0,0 +1,35 @@
+Feature: Null object doubles
+
+  [Test doubles](./test-doubles) are strict by default, raising errors when they receive messages that have not
+  been allowed or expected. You can chain `as_null_object` off of `double` in order to make
+  the double "loose". For any message that has not explicitly allowed or expected, the double
+  will return itself. It acts as a block-hole null object, allowing arbitrarily deep method chains.
+
+  Scenario: `as_null_object` allows arbitrarily deep message chains and returns itself
+    Given a file named "as_null_object_spec.rb" with:
+      """ruby
+      RSpec.describe "as_null_object" do
+        it "returns itself" do
+          dbl = double("Some Collaborator").as_null_object
+          expect(dbl.foo.bar.bazz).to be(dbl)
+        end
+      end
+      """
+     When I run `rspec as_null_object_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Individual methods can still be allowed or expected
+    Given a file named "as_null_object_spec.rb" with:
+      """ruby
+      RSpec.describe "as_null_object" do
+        it "can allow individual methods" do
+          dbl = double("Some Collaborator", :foo => 3).as_null_object
+          allow(dbl).to receive(:bar).and_return(4)
+
+          expect(dbl.foo).to eq(3)
+          expect(dbl.bar).to eq(4)
+        end
+      end
+      """
+     When I run `rspec as_null_object_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/basics/partial_test_doubles.feature b/rspec-mocks/features/basics/partial_test_doubles.feature
new file mode 100644
index 0000000..2b6261f
--- /dev/null
+++ b/rspec-mocks/features/basics/partial_test_doubles.feature
@@ -0,0 +1,70 @@
+Feature: Partial test doubles
+
+  A _partial test double_ is an extension of a real object in a system that is instrumented with
+  test-double like behaviour in the context of a test. This technique is very common in Ruby
+  because we often see class objects acting as global namespaces for methods. For example,
+  in Rails:
+
+  ```ruby
+  person = double("person")
+  allow(Person).to receive(:find) { person }
+  ```
+
+  In this case we're instrumenting Person to return the person object we've defined whenever
+  it receives the `find` message. We can also set a message expectation so that the example
+  fails if `find` is not called:
+
+  ```ruby
+  person = double("person")
+  expect(Person).to receive(:find) { person }
+  ```
+
+  RSpec replaces the method we're stubbing or mocking with its own test-double-like method.
+  At the end of the example, RSpec verifies any message expectations, and then restores the
+  original methods.
+
+  Note: we recommend enabling the [`verify_partial_doubles`](../verifying-doubles/partial-doubles) config option.
+
+  Scenario: Only the specified methods are redefined
+    Given a file named "partial_double_spec.rb" with:
+      """ruby
+      RSpec.describe "A partial double" do
+        # Note: stubbing a string like this is a terrible idea.
+        #       This is just for demonstration purposes.
+        let(:string) { "a string" }
+        before { allow(string).to receive(:length).and_return(500) }
+
+        it "redefines the specified methods" do
+          expect(string.length).to eq(500)
+        end
+
+        it "does not effect other methods" do
+          expect(string.reverse).to eq("gnirts a")
+        end
+      end
+      """
+     When I run `rspec partial_double_spec.rb`
+     Then the examples should all pass
+
+  Scenario: The original method is restored when the example completes
+    Given a file named "partial_double_spec.rb" with:
+      """ruby
+      class User
+        def self.find(id)
+          :original_return_value
+        end
+      end
+
+      RSpec.describe "A partial double" do
+        it "redefines a method" do
+          allow(User).to receive(:find).and_return(:redefined)
+          expect(User.find(3)).to eq(:redefined)
+        end
+
+        it "restores the redefined method after the example completes" do
+          expect(User.find(3)).to eq(:original_return_value)
+        end
+      end
+      """
+     When I run `rspec partial_double_spec.rb --order defined`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/basics/scope.feature b/rspec-mocks/features/basics/scope.feature
new file mode 100644
index 0000000..1bc8a43
--- /dev/null
+++ b/rspec-mocks/features/basics/scope.feature
@@ -0,0 +1,99 @@
+Feature: Scope
+
+  All rspec-mocks constructs have a per-example lifecycle. Message expectations are verified
+  after each example. Doubles, method stubs, stubbed constants, etc. are all cleaned up after
+  each example. This ensures that each example can be run in isolation, and in any order.
+
+  It is perfectly fine to set up doubles, stubs, and message expectations in a
+  `before(:example)` hook, as that hook is executed in the scope of the example:
+
+  ```ruby
+  before(:example) do
+    allow(MyClass).to receive(:foo)
+  end
+  ```
+
+  Since `before(:context)` runs outside the scope of any individual example, usage of
+  rspec-mocks features is not supported there. You can, however, create a temporary scope in
+  _any_ arbitrary context, including in a `before(:context)` hook, using
+  `RSpec::Mocks.with_temporary_scope { }`.
+
+  Scenario: Cannot create doubles in a `before(:context)` hook
+    Given a file named "before_context_spec.rb" with:
+      """ruby
+      RSpec.describe "Creating a double in a before(:context) hook" do
+        before(:context) do
+          @dbl = double(:foo => 13)
+        end
+
+        it "fails before it gets to the examples" do
+          expect(@dbl.foo).to eq(13)
+        end
+      end
+      """
+    When I run `rspec before_context_spec.rb`
+    Then it should fail with:
+      """
+      The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
+      """
+
+  Scenario: Use `with_temporary_scope` to create and use a double in a `before(:context)` hook
+    Given a file named "with_temporary_scope_spec.rb" with:
+      """ruby
+      RSpec.describe "Creating a double in a before(:context) hook" do
+        before(:context) do
+          RSpec::Mocks.with_temporary_scope do
+            dbl = double(:foo => 13)
+            @result = dbl.foo
+          end
+        end
+
+        it "allows a double to be created and used from within a with_temporary_scope block" do
+          expect(@result).to eq(13)
+        end
+      end
+      """
+    When I run `rspec with_temporary_scope_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Doubles cannot be reused in another example
+    Given a file named "leak_test_double_spec.rb" with:
+      """ruby
+      class Account
+        class << self
+          attr_accessor :logger
+        end
+
+        def initialize
+          @balance = 0
+        end
+
+        attr_reader :balance
+
+        def credit(amount)
+          @balance += amount
+          self.class.logger.log("Credited $#{amount}")
+        end
+      end
+
+      RSpec.describe Account do
+        it "logs each credit" do
+          Account.logger = logger = double("Logger")
+          expect(logger).to receive(:log).with("Credited $15")
+          account = Account.new
+          account.credit(15)
+        end
+
+        it "keeps track of the balance" do
+          account = Account.new
+          expect { account.credit(10) }.to change { account.balance }.by(10)
+        end
+      end
+      """
+    When I run `rspec leak_test_double_spec.rb`
+    Then it should fail with the following output:
+      | 2 examples, 1 failure                                                                                                      |
+      |                                                                                                                            |
+      |  1) Account keeps track of the balance                                                                                     |
+      |     Failure/Error: self.class.logger.log("Credited $#{amount}")                                                            |
+      |       Double "Logger" was originally created in one example but has leaked into another example and can no longer be used. |
diff --git a/rspec-mocks/features/basics/spies.feature b/rspec-mocks/features/basics/spies.feature
new file mode 100644
index 0000000..c2e468c
--- /dev/null
+++ b/rspec-mocks/features/basics/spies.feature
@@ -0,0 +1,129 @@
+Feature: Spies
+
+  [Message expectations](./expecting-messages) put an example's expectation at the start, before you've invoked the
+  code-under-test. Many developers prefer using an act-arrange-assert (or given-when-then)
+  pattern for structuring tests. Spies are an alternate type of test double that support this
+  pattern by allowing you to expect that a message has been received after the fact, using
+  `have_received`.
+
+  You can use any test double (or partial double) as a spy, but the double must be setup to
+  spy on the messages you care about. Spies automatically spy on all messages,
+  or you can [allow a message](./allowing-messages) to spy on it.
+
+  `have_received` supports the same fluent interface for [setting constraints](../setting-constraints) that normal message expectations do.
+
+  Note: The `have_received` API shown here will only work if you are using rspec-expectations.
+  Note: `have_received(...).with(...)` is unable to work properly when passed arguments are mutated after the spy records the received message.
+
+  Scenario: Using a spy
+    Given a file named "spy_spec.rb" with:
+      """ruby
+      RSpec.describe "have_received" do
+        it "passes when the message has been received" do
+          invitation = spy('invitation')
+          invitation.deliver
+          expect(invitation).to have_received(:deliver)
+        end
+      end
+      """
+    When I run `rspec spy_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Spy on a method on a partial double
+    Given a file named "partial_double_spy_spec.rb" with:
+      """ruby
+      class Invitation
+        def self.deliver; end
+      end
+
+      RSpec.describe "have_received" do
+        it "passes when the expectation is met" do
+          allow(Invitation).to receive(:deliver)
+          Invitation.deliver
+          expect(Invitation).to have_received(:deliver)
+        end
+      end
+      """
+    When I run `rspec partial_double_spy_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failure when the message has not been received
+    Given a file named "failure_spec.rb" with:
+      """ruby
+      class Invitation
+        def self.deliver; end
+      end
+
+      RSpec.describe "failure when the message has not been received" do
+        example "for a spy" do
+          invitation = spy('invitation')
+          expect(invitation).to have_received(:deliver)
+        end
+
+        example "for a partial double" do
+          allow(Invitation).to receive(:deliver)
+          expect(Invitation).to have_received(:deliver)
+        end
+      end
+      """
+     When I run `rspec failure_spec.rb --order defined`
+     Then it should fail with:
+      """
+        1) failure when the message has not been received for a spy
+           Failure/Error: expect(invitation).to have_received(:deliver)
+             (Double "invitation").deliver(*(any args))
+                 expected: 1 time with any arguments
+                 received: 0 times with any arguments
+      """
+      And it should fail with:
+      """
+        2) failure when the message has not been received for a partial double
+           Failure/Error: expect(Invitation).to have_received(:deliver)
+             (<Invitation (class)>).deliver(*(any args))
+                 expected: 1 time with any arguments
+                 received: 0 times with any arguments
+      """
+
+  Scenario: Set constraints using the fluent interface
+    Given a file named "setting_constraints_spec.rb" with:
+      """ruby
+      RSpec.describe "An invitiation" do
+        let(:invitation) { spy("invitation") }
+
+        before do
+          invitation.deliver("foo at example.com")
+          invitation.deliver("bar at example.com")
+        end
+
+        it "passes when a count constraint is satisfied" do
+          expect(invitation).to have_received(:deliver).twice
+        end
+
+        it "passes when an order constraint is satisifed" do
+          expect(invitation).to have_received(:deliver).with("foo at example.com").ordered
+          expect(invitation).to have_received(:deliver).with("bar at example.com").ordered
+        end
+
+        it "fails when a count constraint is not satisfied" do
+          expect(invitation).to have_received(:deliver).at_least(3).times
+        end
+
+        it "fails when an order constraint is not satisifed" do
+          expect(invitation).to have_received(:deliver).with("bar at example.com").ordered
+          expect(invitation).to have_received(:deliver).with("foo at example.com").ordered
+        end
+      end
+      """
+    When I run `rspec setting_constraints_spec.rb --order defined`
+    Then it should fail with the following output:
+      | 4 examples, 2 failures                                                                           |
+      |                                                                                                  |
+      |  1) An invitiation fails when a count constraint is not satisfied                                |
+      |     Failure/Error: expect(invitation).to have_received(:deliver).at_least(3).times               |
+      |       (Double "invitation").deliver(*(any args))                                                 |
+      |           expected: at least 3 times with any arguments                                          |
+      |           received: 2 times with any arguments                                                   |
+      |                                                                                                  |
+      |  2) An invitiation fails when an order constraint is not satisifed                               |
+      |     Failure/Error: expect(invitation).to have_received(:deliver).with("foo at example.com").ordered |
+      |       Double "invitation" received :deliver out of order                                         |
diff --git a/rspec-mocks/features/basics/test_doubles.feature b/rspec-mocks/features/basics/test_doubles.feature
new file mode 100644
index 0000000..b0cc417
--- /dev/null
+++ b/rspec-mocks/features/basics/test_doubles.feature
@@ -0,0 +1,41 @@
+Feature: Test Doubles
+
+  _Test double_ is a generic term for any object that stands in for a real object during a test
+  (think "stunt double"). You create one using the `double` method. Doubles are "strict" by
+  default -- any message you have not allowed or expected will trigger an error -- but you can
+  [switch a double to being "loose"](./null-object-doubles). When creating a double, you can allow messages (and set
+  their return values) by passing a hash.
+
+  Once you have a test double, you can [allow](./allowing-messages) or [expect](./expecting-messages) messages on it.
+
+  We recommend you use [verifying doubles](../verifying-doubles) whenever possible.
+
+  Scenario: Doubles are strict by default
+    Given a file named "double_spec.rb" with:
+      """ruby
+      RSpec.describe "A test double" do
+        it "raises errors when messages not allowed or expected are received" do
+          dbl = double("Some Collaborator")
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec double_spec.rb`
+     Then it should fail with:
+      """
+      Double "Some Collaborator" received unexpected message :foo with (no args)
+      """
+
+  Scenario: A hash can be used to define allowed messages and return values
+    Given a file named "double_spec.rb" with:
+      """ruby
+      RSpec.describe "A test double" do
+        it "returns canned responses from the methods named in the provided hash" do
+          dbl = double("Some Collaborator", :foo => 3, :bar => 4)
+          expect(dbl.foo).to eq(3)
+          expect(dbl.bar).to eq(4)
+        end
+      end
+      """
+     When I run `rspec double_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/configuring_responses/README.md b/rspec-mocks/features/configuring_responses/README.md
new file mode 100644
index 0000000..25b7317
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/README.md
@@ -0,0 +1,12 @@
+When [allowing](./basics/allowing-messages) or [expecting](./basics/expecting-messages) messages, the default response is to return `nil`. Several
+methods are provided to configure how the test double responds to the message.
+
+* <a href="./configuring-responses/returning-a-value">`and_return`</a>
+* <a href="./configuring-responses/raising-an-error">`and_raise`</a>
+* <a href="./configuring-responses/throwing">`and_throw`</a>
+* <a href="./configuring-responses/yielding">`and_yield`</a>
+* <a href="./configuring-responses/calling-the-original-implementation">`and_call_original`</a>
+
+In addition, you can provide a [block implementation](./configuring-responses/block-implementation) to respond in any manner you wish.
+
+Note: for simplicity, the examples here use `allow` rather than `expect`, but these APIs apply equally to both cases.
diff --git a/rspec-mocks/features/configuring_responses/block_implementation.feature b/rspec-mocks/features/configuring_responses/block_implementation.feature
new file mode 100644
index 0000000..8f1449a
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/block_implementation.feature
@@ -0,0 +1,131 @@
+Feature: Block implementation
+
+  When you pass a block, RSpec will use your block as the implementation of the method. Any
+  arguments (or a block) provided by the caller will be yielded to your block implementation.
+  This feature is extremely flexible, and supports many use cases that are not directly
+  supported by the more declaritive fluent interface.
+
+  You can pass a block to any of the fluent interface methods:
+
+    * `allow(dbl).to receive(:foo) { do_something }`
+    * `allow(dbl).to receive(:foo).with("args") { do_something }`
+    * `allow(dbl).to receive(:foo).once { do_something }`
+    * `allow(dbl).to receive(:foo).ordered { do_something }`
+
+  Some of the more common use cases for block implementations are shown below, but this
+  is not an exhaustive list.
+
+  Scenario: Use a block to specify a return value with a terser syntax
+    Given a file named "return_value_spec.rb" with:
+      """ruby
+      RSpec.describe "Specifying a return value using a block" do
+        it "returns the block's return value" do
+          dbl = double
+          allow(dbl).to receive(:foo) { 14 }
+          expect(dbl.foo).to eq(14)
+        end
+      end
+      """
+     When I run `rspec return_value_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Use a block to verify arguments
+    Given a file named "verify_arguments_spec.rb" with:
+      """ruby
+      RSpec.describe "Verifying arguments using a block" do
+        it "fails when the arguments do not meet the expectations set in the block" do
+          dbl = double
+
+          allow(dbl).to receive(:foo) do |arg|
+            expect(arg).to eq("bar")
+          end
+
+          dbl.foo(nil)
+        end
+      end
+      """
+     When I run `rspec verify_arguments_spec.rb`
+     Then it should fail with:
+      """
+      Failure/Error: expect(arg).to eq("bar")
+      """
+
+  Scenario: Use a block to perform a calculation
+    Given a file named "perform_calculation_spec.rb" with:
+      """ruby
+      RSpec.describe "Performing a calculation using a block" do
+        it "returns the block's return value" do
+          loan = double("Loan", :amount => 100)
+
+          allow(loan).to receive(:required_payment_for_rate) do |rate|
+            loan.amount * rate
+          end
+
+          expect(loan.required_payment_for_rate(0.05)).to eq(5)
+          expect(loan.required_payment_for_rate(0.1)).to eq(10)
+        end
+      end
+      """
+     When I run `rspec perform_calculation_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Yield to the caller's block
+    Given a file named "yield_to_caller_spec.rb" with:
+      """ruby
+      RSpec.describe "When the caller passes a block" do
+        it "can be yielded to from your implementation block" do
+          dbl = double
+          allow(dbl).to receive(:foo) { |&block| block.call(14) }
+          expect { |probe| dbl.foo(&probe) }.to yield_with_args(14)
+        end
+      end
+      """
+     When I run `rspec yield_to_caller_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Delegate to partial double's original implementation within the block
+    Given a file named "delegate_to_original_spec.rb" with:
+      """ruby
+      class Calculator
+        def self.add(x, y)
+          x + y
+        end
+      end
+
+      RSpec.describe "When using a block implementation on a partial double" do
+        it "supports delegating to the original implementation" do
+          original_add = Calculator.method(:add)
+
+          allow(Calculator).to receive(:add) do |x, y|
+            original_add.call(x, y) * 2
+          end
+
+          expect(Calculator.add(2, 5)).to eq(14)
+        end
+      end
+      """
+     When I run `rspec delegate_to_original_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Simulating a transient network failure
+    Given a file named "simulate_transient_network_failure_spec.rb" with:
+      """ruby
+      RSpec.describe "An HTTP API client" do
+        it "can simulate transient network failures" do
+          client = double("MyHTTPClient")
+
+          call_count = 0
+          allow(client).to receive(:fetch_data) do
+            call_count += 1
+            call_count.odd? ? raise("timeout") : { :count => 15 }
+          end
+
+          expect { client.fetch_data }.to raise_error("timeout")
+          expect(client.fetch_data).to eq(:count => 15)
+          expect { client.fetch_data }.to raise_error("timeout")
+          expect(client.fetch_data).to eq(:count => 15)
+        end
+      end
+      """
+     When I run `rspec simulate_transient_network_failure_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/configuring_responses/calling_the_original_implementation.feature b/rspec-mocks/features/configuring_responses/calling_the_original_implementation.feature
new file mode 100644
index 0000000..ecadf35
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/calling_the_original_implementation.feature
@@ -0,0 +1,52 @@
+Feature: Calling the original implementation
+
+  Use `and_call_original` to make a partial double response as it normally would. This can
+  be useful when you want to expect a message without interfering with how it responds. You
+  can also use it to configure the default response for most arguments, and then override
+  that for specific arguments using `with`.
+
+  Note: `and_call_original` is only supported on partial doubles, as normal test doubles do
+  not have an original implementation.
+
+  Background:
+    Given a file named "lib/calculator.rb" with:
+      """ruby
+      class Calculator
+        def self.add(x, y)
+          x + y
+        end
+      end
+      """
+
+  Scenario: `and_call_original` makes the partial double respond as it normally would
+    Given a file named "spec/and_call_original_spec.rb" with:
+      """ruby
+      require 'calculator'
+
+      RSpec.describe "and_call_original" do
+        it "responds as it normally would" do
+          expect(Calculator).to receive(:add).and_call_original
+          expect(Calculator.add(2, 3)).to eq(5)
+        end
+      end
+      """
+    When I run `rspec spec/and_call_original_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `and_call_original` can configure a default response that can be overriden for specific args
+    Given a file named "spec/and_call_original_spec.rb" with:
+      """ruby
+      require 'calculator'
+
+      RSpec.describe "and_call_original" do
+        it "can be overriden for specific arguments using #with" do
+          allow(Calculator).to receive(:add).and_call_original
+          allow(Calculator).to receive(:add).with(2, 3).and_return(-5)
+
+          expect(Calculator.add(2, 2)).to eq(4)
+          expect(Calculator.add(2, 3)).to eq(-5)
+        end
+      end
+      """
+    When I run `rspec spec/and_call_original_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/configuring_responses/raising_an_error.feature b/rspec-mocks/features/configuring_responses/raising_an_error.feature
new file mode 100644
index 0000000..c8d212a
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/raising_an_error.feature
@@ -0,0 +1,28 @@
+Feature: Raising an error
+
+  Use `and_raise` to make the test double raise an error when it receives the message. Any of the following forms are supported:
+
+    * `and_raise(ExceptionClass)`
+    * `and_raise("message")`
+    * `and_raise(ExceptionClass, "message")`
+    * `and_raise(instance_of_an_exception_class)`
+
+  Scenario: Raising an error
+    Given a file named "raises_an_error_spec.rb" with:
+      """ruby
+      RSpec.describe "Making it raise an error" do
+        it "raises the provided exception" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_raise("boom")
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec raises_an_error_spec.rb`
+     Then it should fail with:
+      """
+        1) Making it raise an error raises the provided exception
+           Failure/Error: dbl.foo
+           RuntimeError:
+             boom
+      """
diff --git a/rspec-mocks/features/configuring_responses/returning_a_value.feature b/rspec-mocks/features/configuring_responses/returning_a_value.feature
new file mode 100644
index 0000000..623b251
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/returning_a_value.feature
@@ -0,0 +1,52 @@
+Feature: Returning a value
+
+  Use `and_return` to specify a return value. Pass `and_return` multiple values to specify
+  different return values for consecutive calls. The final value will continue to be returned if
+  the message is received additional times.
+
+  Scenario: Nil is returned by default
+    Given a file named "returns_nil_spec.rb" with:
+      """ruby
+      RSpec.describe "The default response" do
+        it "returns nil when no response has been configured" do
+          dbl = double
+          allow(dbl).to receive(:foo)
+          expect(dbl.foo).to be_nil
+        end
+      end
+      """
+     When I run `rspec returns_nil_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Specify a return value
+    Given a file named "and_return_spec.rb" with:
+      """ruby
+      RSpec.describe "Specifying a return value" do
+        it "returns the specified return value" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_return(14)
+          expect(dbl.foo).to eq(14)
+        end
+      end
+      """
+     When I run `rspec and_return_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Specify different return values for multiple calls
+    Given a file named "multiple_calls_spec.rb" with:
+      """ruby
+      RSpec.describe "When the method is called multiple times" do
+        it "returns the specified values in order, then keeps returning the last value" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_return(1, 2, 3)
+
+          expect(dbl.foo).to eq(1)
+          expect(dbl.foo).to eq(2)
+          expect(dbl.foo).to eq(3)
+          expect(dbl.foo).to eq(3)
+          expect(dbl.foo).to eq(3)
+        end
+      end
+      """
+     When I run `rspec multiple_calls_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/configuring_responses/throwing.feature b/rspec-mocks/features/configuring_responses/throwing.feature
new file mode 100644
index 0000000..c6adbf9
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/throwing.feature
@@ -0,0 +1,36 @@
+Feature: Throwing
+
+  Use `and_throw` to make the test double throw the provided symbol, optionally with the provided argument.
+
+    * `and_throw(:symbol)`
+    * `and_throw(:symbol, argument)`
+
+  Scenario: Throw a symbol
+    Given a file named "and_throw_spec.rb" with:
+      """ruby
+      RSpec.describe "Making it throw a symbol" do
+        it "throws the provided symbol" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_throw(:hello)
+
+          catch :hello do
+            dbl.foo
+            fail "should not get here"
+          end
+        end
+
+        it "includes the provided argument when throwing" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_throw(:hello, "world")
+
+          arg = catch :hello do
+            dbl.foo
+            fail "should not get here"
+          end
+
+          expect(arg).to eq("world")
+        end
+      end
+      """
+     When I run `rspec and_throw_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/configuring_responses/wrapping_the_original_implementation.feature b/rspec-mocks/features/configuring_responses/wrapping_the_original_implementation.feature
new file mode 100644
index 0000000..740ff65
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/wrapping_the_original_implementation.feature
@@ -0,0 +1,53 @@
+Feature: Wrapping the original implementation
+
+  Use `and_wrap_original` to modify a partial double's original response. This can be useful
+  when you want to utilise an external object but mutate it's response. For example if an
+  API returns a large amount of data and for test purposes you'd like to trim it down. You can
+  also use it to configure the default response for most arguments, and then override that for
+  specific arguments using `with`.
+
+  Note: `and_wrap_original` is only supported on partial doubles, as normal test doubles do
+  not have an original implementation.
+
+  Background:
+    Given a file named "lib/api.rb" with:
+      """ruby
+      class API
+        def self.solve_for(x)
+          (1..x).to_a
+        end
+      end
+      """
+
+  Scenario: `and_wrap_original` wraps the original partial double response
+    Given a file named "spec/and_wrap_original_spec.rb" with:
+      """ruby
+      require 'api'
+
+      RSpec.describe "and_wrap_original" do
+        it "responds as it normally would, modified by the block" do
+          expect(API).to receive(:solve_for).and_wrap_original { |m, *args| m.call(*args).first(5) }
+          expect(API.solve_for(100)).to eq [1,2,3,4,5]
+        end
+      end
+      """
+    When I run `rspec spec/and_wrap_original_spec.rb`
+    Then the examples should all pass
+
+  Scenario: `and_wrap_original` can configure a default response that can be overriden for specific args
+    Given a file named "spec/and_wrap_original_spec.rb" with:
+      """ruby
+      require 'api'
+
+      RSpec.describe "and_wrap_original" do
+        it "can be overriden for specific arguments using #with" do
+          allow(API).to receive(:solve_for).and_wrap_original { |m, *args| m.call(*args).first(5) }
+          allow(API).to receive(:solve_for).with(2).and_return([3])
+
+          expect(API.solve_for(20)).to eq [1,2,3,4,5]
+          expect(API.solve_for(2)).to eq [3]
+        end
+      end
+      """
+    When I run `rspec spec/and_wrap_original_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/configuring_responses/yielding.feature b/rspec-mocks/features/configuring_responses/yielding.feature
new file mode 100644
index 0000000..303e5ef
--- /dev/null
+++ b/rspec-mocks/features/configuring_responses/yielding.feature
@@ -0,0 +1,76 @@
+Feature: Yielding
+
+  Use `and_yield` to make the test double yield the provided arguments when it receives the
+  message. If the caller does not provide a block, or the caller's block does not accept the
+  provided arguments, an error will be raised. If you want to yield multiple times, chain
+  multiple `and_yield` calls together.
+
+  Scenario: Yield an argument
+    Given a file named "yield_arguments_spec.rb" with:
+      """ruby
+      RSpec.describe "Making it yield arguments" do
+        it "yields the provided args" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_yield(2, 3)
+
+          x = y = nil
+          dbl.foo { |a, b| x, y = a, b }
+          expect(x).to eq(2)
+          expect(y).to eq(3)
+        end
+      end
+      """
+     When I run `rspec yield_arguments_spec.rb`
+     Then the examples should all pass
+
+  Scenario: It fails when the caller does not provide a block
+    Given a file named "no_caller_block_spec.rb" with:
+      """ruby
+      RSpec.describe "Making it yield" do
+        it "fails when the caller does not provide a block" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_yield(2, 3)
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec no_caller_block_spec.rb`
+     Then it should fail with:
+      """
+      Double asked to yield |[2, 3]| but no block was passed
+      """
+
+  Scenario: It fails when the caller's block does not accept the provided arguments
+    Given a file named "arg_mismatch_spec.rb" with:
+      """ruby
+      RSpec.describe "Making it yield" do
+        it "fails when the caller's block does not accept the provided arguments" do
+          dbl = double
+          allow(dbl).to receive(:foo).and_yield(2, 3)
+          dbl.foo { |x| }
+        end
+      end
+      """
+     When I run `rspec arg_mismatch_spec.rb`
+     Then it should fail with:
+      """
+      Double yielded |2, 3| to block with arity of 1
+      """
+
+  Scenario: Yield multiple times
+    Given a file named "yield_multiple_times_spec.rb" with:
+      """
+      RSpec.describe "Making it yield multiple times" do
+        it "yields the specified args in succession" do
+          yielded = []
+
+          dbl = double
+          allow(dbl).to receive(:foo).and_yield(1).and_yield(2).and_yield(3)
+          dbl.foo { |x| yielded << x }
+
+          expect(yielded).to eq([1, 2, 3])
+        end
+      end
+      """
+    When I run `rspec yield_multiple_times_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/mutating_constants/README.md b/rspec-mocks/features/mutating_constants/README.md
new file mode 100644
index 0000000..1d92a86
--- /dev/null
+++ b/rspec-mocks/features/mutating_constants/README.md
@@ -0,0 +1,78 @@
+### Stubbing
+
+Support is provided for stubbing constants. Like with method stubs, the stubbed constants
+will be restored to their original state when an example completes.
+
+``` ruby
+stub_const("Foo", fake_foo)
+Foo # => fake_foo
+```
+
+Stubbed constant names must be fully qualified; the current module nesting is not
+considered.
+
+``` ruby
+module MyGem
+  class SomeClass; end
+end
+
+module MyGem
+  describe "Something" do
+    let(:fake_class) { Class.new }
+
+    it "accidentally stubs the wrong constant" do
+      # this stubs ::SomeClass (in the top-level namespace),
+      # not MyGem::SomeClass like you probably mean.
+      stub_const("SomeClass", fake_class)
+    end
+
+    it "stubs the right constant" do
+      stub_const("MyGem::SomeClass", fake_class)
+    end
+  end
+end
+```
+
+When you stub a constant that is a module or a class, nested constants on the original
+module or class are not transferred by default, but you can use the
+`:transfer_nested_constants` option to tell rspec-mocks to transfer them:
+
+``` ruby
+class CardDeck
+  SUITS = [:Spades, :Diamonds, :Clubs, :Hearts]
+  NUM_CARDS = 52
+end
+
+fake_class = Class.new
+stub_const("CardDeck", fake_class)
+CardDeck # => fake_class
+CardDeck::SUITS # => raises uninitialized constant error
+CardDeck::NUM_CARDS # => raises uninitialized constant error
+
+stub_const("CardDeck", fake_class, :transfer_nested_constants => true)
+CardDeck::SUITS # => [:Spades, :Diamonds, :Clubs, :Hearts]
+CardDeck::NUM_CARDS # => 52
+
+stub_const("CardDeck", fake_class, :transfer_nested_constants => [:SUITS])
+CardDeck::SUITS # => [:Spades, :Diamonds, :Clubs, :Hearts]
+CardDeck::NUM_CARDS # => raises uninitialized constant error
+```
+
+### Hiding
+
+Support is also provided for hiding constants. Hiding a constant temporarily removes it; it is
+restored to its original value after the test completes.
+
+```ruby
+FOO = 42
+hide_const("FOO")
+FOO => NameError: uninitialized constant FOO
+```
+
+Like stubbed constants, names must be fully qualified.
+
+Hiding constants that are already undefined has no effect.
+
+```ruby
+hide_const("NO_OP")
+```
diff --git a/rspec-mocks/features/mutating_constants/hide_defined_constant.feature b/rspec-mocks/features/mutating_constants/hide_defined_constant.feature
new file mode 100644
index 0000000..559542b
--- /dev/null
+++ b/rspec-mocks/features/mutating_constants/hide_defined_constant.feature
@@ -0,0 +1,64 @@
+Feature: Hide Defined Constant
+
+  Use `hide_const` to remove a constant for the duration of a test.
+
+  Scenario: Hide top-level constant
+    Given a file named "hide_const_spec.rb" with:
+      """ruby
+      FOO = 7
+
+      RSpec.describe "hiding FOO" do
+        it "can hide FOO" do
+          hide_const("FOO")
+          expect { FOO }.to raise_error(NameError)
+        end
+
+        it "restores the hidden constant when the example completes" do
+          expect(FOO).to eq(7)
+        end
+      end
+      """
+    When I run `rspec hide_const_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Hide nested constant
+    Given a file named "hide_const_spec.rb" with:
+      """ruby
+      module MyGem
+        class SomeClass
+          FOO = 7
+        end
+      end
+
+      module MyGem
+        RSpec.describe SomeClass do
+          it "hides the nested constant when it is fully qualified" do
+            hide_const("MyGem::SomeClass::FOO")
+            expect { SomeClass::FOO }.to raise_error(NameError)
+          end
+
+          it "restores the hidden constant when the example completes" do
+            expect(MyGem::SomeClass::FOO).to eq(7)
+          end
+        end
+      end
+      """
+    When I run `rspec hide_const_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Hiding undefined constant
+    Given a file named "hide_const_spec.rb" with:
+      """ruby
+      RSpec.describe "hiding UNDEFINED_CONSTANT" do
+        it "has no effect" do
+          hide_const("UNDEFINED_CONSTANT")
+          expect { UNDEFINED_CONSTANT }.to raise_error(NameError)
+        end
+
+        it "is still undefined after the example completes" do
+          expect { UNDEFINED_CONSTANT }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec hide_const_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/mutating_constants/hide_undefined_constant.feature b/rspec-mocks/features/mutating_constants/hide_undefined_constant.feature
new file mode 100644
index 0000000..629ab23
--- /dev/null
+++ b/rspec-mocks/features/mutating_constants/hide_undefined_constant.feature
@@ -0,0 +1,22 @@
+Feature: Hide Undefined Constant
+
+  Hiding a constant that is already undefined is a no-op. This can be useful when a spec file
+  may run in either an isolated environment (e.g. when running one spec file) or in a full
+  environment with all parts of your code base loaded (e.g. when running your entire suite).
+
+  Scenario: Hiding undefined constant
+    Given a file named "hide_const_spec.rb" with:
+      """ruby
+      RSpec.describe "hiding UNDEFINED_CONSTANT" do
+        it "has no effect" do
+          hide_const("UNDEFINED_CONSTANT")
+          expect { UNDEFINED_CONSTANT }.to raise_error(NameError)
+        end
+
+        it "is still undefined after the example completes" do
+          expect { UNDEFINED_CONSTANT }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec hide_const_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/mutating_constants/stub_defined_constant.feature b/rspec-mocks/features/mutating_constants/stub_defined_constant.feature
new file mode 100644
index 0000000..4d61e38
--- /dev/null
+++ b/rspec-mocks/features/mutating_constants/stub_defined_constant.feature
@@ -0,0 +1,77 @@
+Feature: Stub Defined Constant
+
+  Use `stub_const` to stub constants. When the constant is already defined, the stubbed value
+  will replace the original value for the duration of the example.
+
+  Scenario: Stub top-level constant
+    Given a file named "stub_const_spec.rb" with:
+      """ruby
+      FOO = 7
+
+      RSpec.describe "stubbing FOO" do
+        it "can stub FOO with a different value" do
+          stub_const("FOO", 5)
+          expect(FOO).to eq(5)
+        end
+
+        it "restores the stubbed constant when the example completes" do
+          expect(FOO).to eq(7)
+        end
+      end
+      """
+    When I run `rspec stub_const_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Stub nested constant
+    Given a file named "stub_const_spec.rb" with:
+      """ruby
+      module MyGem
+        class SomeClass
+          FOO = 7
+        end
+      end
+
+      module MyGem
+        RSpec.describe SomeClass do
+          it "stubs the nested constant when it is fully qualified" do
+            stub_const("MyGem::SomeClass::FOO", 5)
+            expect(SomeClass::FOO).to eq(5)
+          end
+        end
+      end
+      """
+    When I run `rspec stub_const_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Transfer nested constants
+    Given a file named "stub_const_spec.rb" with:
+      """ruby
+      module MyGem
+        class SomeClass
+          FOO = 7
+        end
+      end
+
+      module MyGem
+        RSpec.describe SomeClass do
+          let(:fake_class) { Class.new }
+
+          it "does not transfer nested constants by default" do
+            stub_const("MyGem::SomeClass", fake_class)
+            expect { SomeClass::FOO }.to raise_error(NameError)
+          end
+
+          it "transfers nested constants when using :transfer_nested_constants => true" do
+            stub_const("MyGem::SomeClass", fake_class, :transfer_nested_constants => true)
+            expect(SomeClass::FOO).to eq(7)
+          end
+
+          it "can specify a list of nested constants to transfer" do
+            stub_const("MyGem::SomeClass", fake_class, :transfer_nested_constants => [:FOO])
+            expect(SomeClass::FOO).to eq(7)
+          end
+        end
+      end
+      """
+    When I run `rspec stub_const_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/mutating_constants/stub_undefined_constant.feature b/rspec-mocks/features/mutating_constants/stub_undefined_constant.feature
new file mode 100644
index 0000000..002f735
--- /dev/null
+++ b/rspec-mocks/features/mutating_constants/stub_undefined_constant.feature
@@ -0,0 +1,50 @@
+Feature: Stub Undefined Constant
+
+  Use `stub_const` to stub constants. When the constant is not already defined, all the
+  necessary intermediary modules will be dynamically created. When the example completes,
+  the intermediary module constants will be removed to return the constant state to how it
+  started.
+
+  Scenario: Stub top-level constant
+    Given a file named "stub_const_spec.rb" with:
+      """ruby
+      RSpec.describe "stubbing FOO" do
+        it "can stub undefined constant FOO" do
+          stub_const("FOO", 5)
+          expect(FOO).to eq(5)
+        end
+
+        it "undefines the constant when the example completes" do
+          expect { FOO }.to raise_error(NameError)
+        end
+      end
+      """
+    When I run `rspec stub_const_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Stub nested constant
+    Given a file named "stub_const_spec.rb" with:
+      """ruby
+      module MyGem
+        class SomeClass
+        end
+      end
+
+      module MyGem
+        RSpec.describe SomeClass do
+          it "can stub an arbitrarily deep constant that is undefined" do
+            expect(defined?(SomeClass::A)).to be_falsey
+            stub_const("MyGem::SomeClass::A::B::C", 3)
+            expect(SomeClass::A::B::C).to eq(3)
+            expect(SomeClass::A).to be_a(Module)
+          end
+
+          it 'undefines the intermediary constants that were dynamically created' do
+            expect(defined?(SomeClass)).to be_truthy
+            expect(defined?(SomeClass::A)).to be_falsey
+          end
+        end
+      end
+      """
+    When I run `rspec stub_const_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/old_syntax/README.md b/rspec-mocks/features/old_syntax/README.md
new file mode 100644
index 0000000..a2ead9e
--- /dev/null
+++ b/rspec-mocks/features/old_syntax/README.md
@@ -0,0 +1,35 @@
+Historically, rspec-mocks has used a monkey-patched syntax to allow you to mock or stub any object:
+
+```ruby
+obj.stub(:foo).and_return(15)
+obj.should_receive(:bar)
+```
+
+Unfortunately, this is prone to weird, confusing failures when applied to [delegate/proxy
+objects](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#delegation_issues). For a method like `stub` to work properly, it must be defined on every object in the
+system, but RSpec does not own every object in the system and cannot ensure that it always
+works consistently.
+
+For this reason, in RSpec 2.14, we introduced a new syntax that avoids monkey patching
+altogether. It's the syntax shown in all examples of this documentation outside of this
+directory. As of RSpec 3, we consider this to be the main, recommended syntax of rspec-
+mocks. The old monkey-patched syntax continues to work, but you will get a deprecation
+warning if you use it without explicitly opting-in to it:
+
+```ruby
+# If you're using rspec-core:
+RSpec.configure do |config|
+  config.mock_with :rspec do |mocks|
+    mocks.syntax = :should
+  end
+end
+
+# Or, if you're using rspec-mocks in another context:
+RSpec::Mocks.configuration.syntax = :should
+```
+
+We have no plans to ever kill the old syntax, but we may extract it into an external gem in
+RSpec 4.
+
+If you have an old project that uses the old syntax and you want to update it to the current
+syntax, checkout [transpec](http://yujinakayama.me/transpec/).
diff --git a/rspec-mocks/features/old_syntax/any_instance.feature b/rspec-mocks/features/old_syntax/any_instance.feature
new file mode 100644
index 0000000..0a4d85f
--- /dev/null
+++ b/rspec-mocks/features/old_syntax/any_instance.feature
@@ -0,0 +1,105 @@
+ at allow-old-syntax
+Feature: `any_instance`
+
+  `any_instance` is the old way to stub or mock any instance of a class but carries the baggage of a global monkey patch on all classes.
+  Note that we [generally recommend against](../working-with-legacy-code/any-instance) using this feature.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+          mocks.syntax = :should
+        end
+      end
+      """
+    And a file named ".rspec" with:
+      """
+      --require spec_helper
+      """
+
+  Scenario: Stub a method on any instance of a class
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "Stubbing a method with any_instance" do
+        it "returns the specified value on any instance of the class" do
+          Object.any_instance.stub(:foo).and_return(:return_value)
+
+          o = Object.new
+          expect(o.foo).to eq(:return_value)
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Stub multiple methods on any instance of a class
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "Stubbing multiple methods with any_instance" do
+        it "returns the specified values for the givne messages" do
+          Object.any_instance.stub(:foo => 'foo', :bar => 'bar')
+
+          o = Object.new
+          expect(o.foo).to eq('foo')
+          expect(o.bar).to eq('bar')
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Stubbing any instance of a class with specific arguments
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "Stubbing any instance with arguments" do
+        it "returns the stubbed value when arguments match" do
+          Object.any_instance.stub(:foo).with(:param_one, :param_two).and_return(:result_one)
+          Object.any_instance.stub(:foo).with(:param_three, :param_four).and_return(:result_two)
+
+          o = Object.new
+          expect(o.foo(:param_one, :param_two)).to eq(:result_one)
+          expect(o.foo(:param_three, :param_four)).to eq(:result_two)
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Block implementation is passed the receiver as first arg
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "Stubbing any instance of a class" do
+        it 'yields the receiver to the block implementation' do
+          String.any_instance.stub(:slice) do |value, start, length|
+            value[start, length]
+          end
+
+          expect('string'.slice(2, 3)).to eq('rin')
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Expect a message on any instance of a class
+    Given a file named "spec/example_spec.rb" with:
+      """ruby
+      RSpec.describe "Expecting a message on any instance of a class" do
+        before do
+          Object.any_instance.should_receive(:foo)
+        end
+
+        it "passes when an instance receives the message" do
+          Object.new.foo
+        end
+
+        it "fails when no instance receives the message" do
+          Object.new.to_s
+        end
+      end
+      """
+    When I run `rspec spec/example_spec.rb`
+    Then it should fail with the following output:
+      | 2 examples, 1 failure |
+      | Exactly one instance should have received the following message(s) but didn't: foo |
diff --git a/rspec-mocks/features/old_syntax/should_receive.feature b/rspec-mocks/features/old_syntax/should_receive.feature
new file mode 100644
index 0000000..5e7b4d9
--- /dev/null
+++ b/rspec-mocks/features/old_syntax/should_receive.feature
@@ -0,0 +1,90 @@
+ at allow-old-syntax
+Feature: `should_receive`
+
+  `should_receive` is the old way to [expect messages](../basics/expecting-messages) but carries the
+  baggage of a global monkey patch on all objects. It supports the
+  same fluent interface for [setting constraints](../setting-constraints) and [configuring responses](../configuring-responses).
+
+  Similarly, you can use `should_not_receive` to set a negative message expectation.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+          mocks.syntax = :should
+        end
+      end
+      """
+    And a file named ".rspec" with:
+      """
+      --require spec_helper
+      """
+
+  Scenario: Failing positive message expectation
+    Given a file named "spec/unfulfilled_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "An unfulfilled message expectation" do
+        it "triggers a failure" do
+          dbl = double("Some Collaborator")
+          dbl.should_receive(:foo)
+        end
+      end
+      """
+     When I run `rspec spec/unfulfilled_message_expectation_spec.rb`
+     Then it should fail with:
+      """
+        1) An unfulfilled message expectation triggers a failure
+           Failure/Error: dbl.should_receive(:foo)
+             (Double "Some Collaborator").foo(*(any args))
+                 expected: 1 time with any arguments
+                 received: 0 times with any arguments
+      """
+
+  Scenario: Passing positive message expectation
+    Given a file named "spec/fulfilled_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "A fulfilled message expectation" do
+        it "passes" do
+          dbl = double("Some Collaborator")
+          dbl.should_receive(:foo)
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec spec/fulfilled_message_expectation_spec.rb`
+     Then the examples should all pass
+
+  Scenario: Failing negative message expectation
+    Given a file named "spec/negative_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "A negative message expectation" do
+        it "fails when the message is received" do
+          dbl = double("Some Collaborator").as_null_object
+          dbl.should_not_receive(:foo)
+          dbl.foo
+        end
+      end
+      """
+     When I run `rspec spec/negative_message_expectation_spec.rb`
+     Then it should fail with:
+      """
+        1) A negative message expectation fails when the message is received
+           Failure/Error: dbl.foo
+             (Double "Some Collaborator").foo(no args)
+                 expected: 0 times with any arguments
+                 received: 1 time
+      """
+
+  Scenario: Passing negative message expectation
+    Given a file named "spec/negative_message_expectation_spec.rb" with:
+      """ruby
+      RSpec.describe "A negative message expectation" do
+        it "passes if the message is never received" do
+          dbl = double("Some Collaborator").as_null_object
+          dbl.should_not_receive(:foo)
+        end
+      end
+      """
+     When I run `rspec spec/negative_message_expectation_spec.rb`
+     Then the examples should all pass
diff --git a/rspec-mocks/features/old_syntax/stub.feature b/rspec-mocks/features/old_syntax/stub.feature
new file mode 100644
index 0000000..e08ea5e
--- /dev/null
+++ b/rspec-mocks/features/old_syntax/stub.feature
@@ -0,0 +1,51 @@
+ at allow-old-syntax
+Feature: `stub`
+
+  `stub` is the old way to [allow messages](../basics/allowing-messages) but carries the baggage of a
+  global monkey patch on all objects. It supports the same fluent
+  interface for [setting constraints](../setting-constraints) and [configuring responses](../configuring-responses). You can also pass `stub` a hash
+  of message/return-value pairs, which acts like `allow(obj).to receive_messages(hash)`,
+  but does not support further customization through the fluent interface.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+          mocks.syntax = :should
+        end
+      end
+      """
+    And a file named ".rspec" with:
+      """
+      --require spec_helper
+      """
+
+  Scenario: Stub a method
+    Given a file named "spec/stub_spec.rb" with:
+      """ruby
+      RSpec.describe "Stubbing a method" do
+        it "configures how the object responds" do
+          dbl = double
+          dbl.stub(:foo).and_return(13)
+          expect(dbl.foo).to eq(13)
+        end
+      end
+      """
+    When I run `rspec spec/stub_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Stub multiple methods by passing a hash
+    Given a file named "spec/stub_multiple_methods_spec.rb" with:
+      """ruby
+      RSpec.describe "Stubbing multiple methods" do
+        it "stubs each named method with the given return value" do
+          dbl = double
+          dbl.stub(:foo => 13, :bar => 10)
+          expect(dbl.foo).to eq(13)
+          expect(dbl.bar).to eq(10)
+        end
+      end
+      """
+    When I run `rspec spec/stub_multiple_methods_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/old_syntax/stub_chain.feature b/rspec-mocks/features/old_syntax/stub_chain.feature
new file mode 100644
index 0000000..036d52f
--- /dev/null
+++ b/rspec-mocks/features/old_syntax/stub_chain.feature
@@ -0,0 +1,69 @@
+ at allow-old-syntax
+Feature: `stub_chain`
+
+  `stub_chain` is the old way to [allow a message chain](../working-with-legacy-code/message-chains) but carries the
+  baggage of a global monkey patch on all objects. As with
+  `receive_message_chain`, use with care; we recommend treating usage of `stub_chain` as a
+  code smell.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+          mocks.syntax = :should
+        end
+      end
+      """
+    And a file named ".rspec" with:
+      """
+      --require spec_helper
+      """
+
+  Scenario: Use `stub_chain` on a double
+    Given a file named "spec/stub_chain_spec.rb" with:
+      """ruby
+      RSpec.describe "Using stub_chain on a double" do
+        let(:dbl) { double }
+
+        example "using a string and a block" do
+          dbl.stub_chain("foo.bar") { :baz }
+          expect(dbl.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a hash" do
+          dbl.stub_chain(:foo, :bar => :baz)
+          expect(dbl.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a block" do
+          dbl.stub_chain(:foo, :bar) { :baz }
+          expect(dbl.foo.bar).to eq(:baz)
+        end
+      end
+      """
+    When I run `rspec spec/stub_chain_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `stub_chain` on any instance of a class
+    Given a file named "spec/stub_chain_spec.rb" with:
+      """ruby
+      RSpec.describe "Using any_instance.stub_chain" do
+        example "using a string and a block" do
+          Object.any_instance.stub_chain("foo.bar") { :baz }
+          expect(Object.new.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a hash" do
+          Object.any_instance.stub_chain(:foo, :bar => :baz)
+          expect(Object.new.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a block" do
+          Object.any_instance.stub_chain(:foo, :bar) { :baz }
+          expect(Object.new.foo.bar).to eq(:baz)
+        end
+      end
+      """
+    When I run `rspec spec/stub_chain_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/old_syntax/unstub.feature b/rspec-mocks/features/old_syntax/unstub.feature
new file mode 100644
index 0000000..fd6a45d
--- /dev/null
+++ b/rspec-mocks/features/old_syntax/unstub.feature
@@ -0,0 +1,43 @@
+ at allow-old-syntax
+Feature: `unstub`
+
+  `unstub` removes a method stub, essentially cleaning up the method
+  stub early, rather than waiting for the cleanup that runs at the end
+  of the example. The newer non-monkey-patching syntax does not have a direct
+  equivalent but in most situations you can achieve the same behavior using
+  [`and_call_original`](../configuring-responses/calling-the-original-implementation). The difference is that `obj.unstub(:foo)` completely cleans up the `foo`
+  method stub, whereas `allow(obj).to receive(:foo).and_call_original` continues to
+  observe calls to the method (important when you are using [spies](../basics/spies)), which could affect the
+  method's behavior if it does anything with `caller` as it will include additional rspec stack
+  frames.
+
+  Background:
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+          mocks.syntax = :should
+        end
+      end
+      """
+    And a file named ".rspec" with:
+      """
+      --require spec_helper
+      """
+
+  Scenario: Unstub a method
+    Given a file named "spec/unstub_spec.rb" with:
+      """ruby
+      RSpec.describe "Unstubbing a method" do
+        it "restores the original behavior" do
+          string = "hello world"
+          string.stub(:reverse) { "hello dlrow" }
+
+          expect {
+            string.unstub(:reverse)
+          }.to change { string.reverse }.from("hello dlrow").to("dlrow olleh")
+        end
+      end
+      """
+    When I run `rspec spec/unstub_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/outside_rspec/minitest.feature b/rspec-mocks/features/outside_rspec/minitest.feature
new file mode 100644
index 0000000..8e43bd7
--- /dev/null
+++ b/rspec-mocks/features/outside_rspec/minitest.feature
@@ -0,0 +1,80 @@
+Feature: Integrate with Minitest
+
+  rspec-mocks is a stand-alone gem that can be integrated with any test framework. The
+  example below demonstrates using rspec-mocks with [minitest](http://docs.seattlerb.org/minitest/), but these steps
+  would apply when integrating rspec-mocks with any library or framework:
+
+    * Include `RSpec::Mocks::ExampleMethods` in your test context. This provides rspec-mocks' API.
+    * Call `RSpec::Mocks.setup` before a test begins.
+    * Call `RSpec::Mocks.verify` after a test completes to verify message expectations. Note
+      that this step is optional; rspec-core, for example, skips this when an example has already failed.
+    * Call `RSpec::Mocks.teardown` after a test completes (and after `verify`) to cleanup. This
+      _must_ be called, even if an error has occurred, so it generally goes in an `ensure` clause.
+
+  Scenario: Use rspec-mocks with Minitest
+    Given a file named "test/test_helper.rb" with:
+      """ruby
+      require 'minitest/autorun'
+      require 'rspec/mocks'
+
+      module MinitestRSpecMocksIntegration
+        include ::RSpec::Mocks::ExampleMethods
+
+        def before_setup
+          ::RSpec::Mocks.setup
+          super
+        end
+
+        def after_teardown
+          super
+          ::RSpec::Mocks.verify
+        ensure
+          ::RSpec::Mocks.teardown
+        end
+      end
+
+      Minitest::Test.send(:include, MinitestRSpecMocksIntegration)
+      """
+    And a file named "test/rspec_mocks_test.rb" with:
+      """ruby
+      require 'test_helper'
+
+      class RSpecMocksTest < Minitest::Test
+        def test_passing_positive_expectation
+          dbl = double
+          expect(dbl).to receive(:message)
+          dbl.message
+        end
+
+        def test_failing_positive_expectation
+          dbl = double
+          expect(dbl).to receive(:message)
+        end
+
+        def test_passing_negative_expectation
+          dbl = double
+          expect(dbl).to_not receive(:message)
+        end
+
+        def test_failing_negative_expectation
+          dbl = double
+          expect(dbl).to_not receive(:message)
+          dbl.message
+        end
+      end
+      """
+     When I run `ruby -Itest test/rspec_mocks_test.rb`
+     Then it should fail with the following output:
+       |   1) Error:                                                       |
+       | RSpecMocksTest#test_failing_negative_expectation:                 |
+       | RSpec::Mocks::MockExpectationError: (Double).message(no args)     |
+       |     expected: 0 times with any arguments                          |
+       |     received: 1 time                                              |
+       |                                                                   |
+       |   2) Error:                                                       |
+       | RSpecMocksTest#test_failing_positive_expectation:                 |
+       | RSpec::Mocks::MockExpectationError: (Double).message(*(any args)) |
+       |     expected: 1 time with any arguments                           |
+       |     received: 0 times with any arguments                          |
+       |                                                                   |
+       |  4 runs, 0 assertions, 0 failures, 2 errors, 0 skips              |
diff --git a/rspec-mocks/features/outside_rspec/standalone.feature b/rspec-mocks/features/outside_rspec/standalone.feature
new file mode 100644
index 0000000..862e470
--- /dev/null
+++ b/rspec-mocks/features/outside_rspec/standalone.feature
@@ -0,0 +1,33 @@
+Feature: Standalone
+
+  `require "rspec/mocks/standalone"` to expose the API at the top level (e.g. `main`) outside
+  the RSpec environment in a REPL like IRB or in a one-off script.
+
+  Scenario: Allow a message outside RSpec
+    Given a file named "example.rb" with:
+      """ruby
+      require "rspec/mocks/standalone"
+
+      greeter = double("greeter")
+      allow(greeter).to receive(:say_hi) { "Hello!" }
+      puts greeter.say_hi
+      """
+    When I run `ruby example.rb`
+    Then the output should contain "Hello!"
+
+  Scenario: Expect a message outside RSpec
+    Given a file named "example.rb" with:
+      """ruby
+      require "rspec/mocks/standalone"
+
+      greeter = double("greeter")
+      expect(greeter).to receive(:say_hi)
+
+      RSpec::Mocks.verify
+      """
+    When I run `ruby example.rb`
+    Then it should fail with the following output:
+      | (Double "greeter").say_hi(*(any args)) |
+      | RSpec::Mocks::MockExpectationError     |
+      | expected: 1 time with any arguments    |
+      | received: 0 times with any arguments   |
diff --git a/rspec-mocks/features/setting_constraints/README.md b/rspec-mocks/features/setting_constraints/README.md
new file mode 100644
index 0000000..d7d6c62
--- /dev/null
+++ b/rspec-mocks/features/setting_constraints/README.md
@@ -0,0 +1,6 @@
+RSpec provides a fluent interface off of `expect(...).to receive(...)` that allows you to
+further constrain what you expect: the arguments, the number of times, and the ordering of
+multiple messages.
+
+Although not shown here, this fluent interface is also supported by [spies](./basics/spies), off of
+`have_received(...)`.
diff --git a/rspec-mocks/features/setting_constraints/matching_arguments.feature b/rspec-mocks/features/setting_constraints/matching_arguments.feature
new file mode 100644
index 0000000..638a2a3
--- /dev/null
+++ b/rspec-mocks/features/setting_constraints/matching_arguments.feature
@@ -0,0 +1,98 @@
+Feature: Matching arguments
+
+  Use `with` to specify the expected arguments. A [message expectation](../basics/expecting-messages) constrained by `with`
+  will only be satisfied when called with matching arguments. A canned response for an
+  [allowed message](../basics/allowing-messages) will only be used when the arguments match.
+
+  | To match...                                         | ...use an expression like:      | ...which matches calls like:          |
+  | --------------------------------------------------- | ------------------------------- | ------------------------------------- |
+  | Literal arguments                                   | `with(1, true)`                 | `foo(1, true)`                        |
+  | Anything that supports case equality (`===`)        | `with(/bar/)`                   | `foo("barn")`                         |
+  | Any list of args                                    | `with(any_args)`                | `foo()`<br>`foo(1)`<br>`foo(:bar, 2)` |
+  | Any sublist of args (like an arg splat)             | `with(1, any_args)`             | `foo(1)`<br>`foo(1, :bar, :bazz)`     |
+  | An empty list of args                               | `with(no_args)`                 | `foo()`                               |
+  | Anything for a given positional arg                 | `with(3, anything)`             | `foo(3, nil)`<br>`foo(3, :bar)`       |
+  | Against an interface                                | `with(duck_type(:each))`        | `foo([])`                             |
+  | A boolean                                           | `with(3, boolean)`              | `foo(3, true)`<br>`foo(3, false)`     |
+  | A subset of a hash                                  | `with(hash_including(:a => 1))` | `foo(:a => 1, :b => 2)`               |
+  | An excluded subset of a hash                        | `with(hash_excluding(:a => 1))` | `foo(:b => 2)`                        |
+  | A subset of an array                                | `with(array_including(:a, :b))` | `foo([:a, :b, :c])`                   |
+  | An instance of a specific class                     | `with(instance_of(Fixnum))`     | `foo(3)`                              |
+  | An object with a given module in its ancestors list | `with(kind_of(Numeric))`        | `foo(3)`                              |
+  | Any RSpec matcher                                   | `with(<matcher>)`               | `foo(<object that matches>)`          |
+
+  Scenario: Basic example
+    Given a file named "basic_example_spec.rb" with:
+      """ruby
+      RSpec.describe "Constraining a message expectation using with" do
+        let(:dbl) { double }
+        before { expect(dbl).to receive(:foo).with(1, anything, /bar/) }
+
+        it "passes when the args match" do
+          dbl.foo(1, nil, "barn")
+        end
+
+        it "fails when the args do not match" do
+          dbl.foo(1, nil, "other")
+        end
+      end
+      """
+    When I run `rspec basic_example_spec.rb`
+    Then it should fail with the following output:
+      | 2 examples, 1 failure                            |
+      |                                                  |
+      | Failure/Error: dbl.foo(1, nil, "other")          |
+      |   Double received :foo with unexpected arguments |
+      |     expected: (1, anything, /bar/)               |
+      |          got: (1, nil, "other")                  |
+
+  Scenario: Using a custom matcher
+    Given a file named "custom_matcher_spec.rb" with:
+      """ruby
+      RSpec::Matchers.define :a_multiple_of do |x|
+        match { |actual| (actual % x).zero? }
+      end
+
+      RSpec.describe "Using a custom matcher" do
+        let(:dbl) { double }
+        before { expect(dbl).to receive(:foo).with(a_multiple_of(3)) }
+
+        it "passes when the args match" do
+          dbl.foo(12)
+        end
+
+        it "fails when the args do not match" do
+          dbl.foo(13)
+        end
+      end
+      """
+    When I run `rspec custom_matcher_spec.rb`
+    Then it should fail with the following output:
+      | 2 examples, 1 failure                            |
+      |                                                  |
+      | Failure/Error: dbl.foo(13)                       |
+      |   Double received :foo with unexpected arguments |
+      |     expected: (a multiple of 3)                  |
+      |          got: (13)                               |
+
+  Scenario: Responding differently based on the arguments
+    Given a file named "responding_differently_spec.rb" with:
+      """ruby
+      RSpec.describe "Using #with to constrain responses" do
+        specify "its response depends on the arguments" do
+          dbl = double
+
+          # Set a default for any unmatched args
+          allow(dbl).to receive(:foo).and_return(:default)
+
+          allow(dbl).to receive(:foo).with(1).and_return(1)
+          allow(dbl).to receive(:foo).with(2).and_return(2)
+
+          expect(dbl.foo(0)).to eq(:default)
+          expect(dbl.foo(1)).to eq(1)
+          expect(dbl.foo(2)).to eq(2)
+        end
+      end
+      """
+    When I run `rspec responding_differently_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/setting_constraints/message_order.feature b/rspec-mocks/features/setting_constraints/message_order.feature
new file mode 100644
index 0000000..11dc22b
--- /dev/null
+++ b/rspec-mocks/features/setting_constraints/message_order.feature
@@ -0,0 +1,63 @@
+Feature: Message Order
+
+  You can use `ordered` to constrain the order of multiple message expectations. This is not
+  generally recommended because in most situations the order doesn't matter and using
+  `ordered` would make your spec brittle, but it's occasionally useful. When you use `ordered`,
+  the example will only pass if the messages are received in the declared order.
+
+  Scenario: Passing example
+    Given a file named "passing_example_spec.rb" with:
+      """ruby
+      RSpec.describe "Constraining order" do
+        it "passes when the messages are received in declared order" do
+          collaborator_1 = double("Collaborator 1")
+          collaborator_2 = double("Collaborator 2")
+
+          expect(collaborator_1).to receive(:step_1).ordered
+          expect(collaborator_2).to receive(:step_2).ordered
+          expect(collaborator_1).to receive(:step_3).ordered
+
+          collaborator_1.step_1
+          collaborator_2.step_2
+          collaborator_1.step_3
+        end
+      end
+      """
+    When I run `rspec passing_example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failing examples
+    Given a file named "failing_examples_spec.rb" with:
+      """ruby
+      RSpec.describe "Constraining order" do
+        it "fails when messages are received out of order on one collaborator" do
+          collaborator_1 = double("Collaborator 1")
+
+          expect(collaborator_1).to receive(:step_1).ordered
+          expect(collaborator_1).to receive(:step_2).ordered
+
+          collaborator_1.step_2
+          collaborator_1.step_1
+        end
+
+        it "fails when messages are received out of order between collaborators" do
+          collaborator_1 = double("Collaborator 1")
+          collaborator_2 = double("Collaborator 2")
+
+          expect(collaborator_1).to receive(:step_1).ordered
+          expect(collaborator_2).to receive(:step_2).ordered
+
+          collaborator_2.step_2
+          collaborator_1.step_1
+        end
+      end
+      """
+    When I run `rspec failing_examples_spec.rb --order defined`
+    Then the examples should all fail, producing the following output:
+      |  1) Constraining order fails when messages are received out of order on one collaborator   |
+      |     Failure/Error: collaborator_1.step_2                                                   |
+      |       Double "Collaborator 1" received :step_2 out of order                                |
+      |                                                                                            |
+      |  2) Constraining order fails when messages are received out of order between collaborators |
+      |     Failure/Error: collaborator_2.step_2                                                   |
+      |       Double "Collaborator 2" received :step_2 out of order                                |
diff --git a/rspec-mocks/features/setting_constraints/receive_counts.feature b/rspec-mocks/features/setting_constraints/receive_counts.feature
new file mode 100644
index 0000000..de9c7c8
--- /dev/null
+++ b/rspec-mocks/features/setting_constraints/receive_counts.feature
@@ -0,0 +1,189 @@
+Feature: Receive Counts
+
+  When [expecting a message](../basics/expecting-messages), you can specify how many times you expect the message to be
+  received:
+
+    * `expect(...).to receive(...).once`
+    * `expect(...).to receive(...).twice`
+    * `expect(...).to receive(...).exactly(n).times`
+    * `expect(...).to receive(...).at_least(:once)`
+    * `expect(...).to receive(...).at_least(:twice)`
+    * `expect(...).to receive(...).at_least(n).times`
+    * `expect(...).to receive(...).at_most(:once)`
+    * `expect(...).to receive(...).at_most(:twice)`
+    * `expect(...).to receive(...).at_most(n).times`
+
+  If you don't specify an expected receive count, it defaults to `once`.
+
+  Background:
+    Given a file named "lib/account.rb" with:
+      """ruby
+      class Account
+        def initialize(logger)
+          @logger = logger
+        end
+
+        def open
+          @logger.account_opened
+        end
+      end
+      """
+
+  Scenario: Passing examples
+    Given a file named "spec/account_spec.rb" with:
+      """ruby
+      require 'account'
+
+      RSpec.describe Account do
+        let(:logger)  { double("Logger") }
+        let(:account) { Account.new(logger) }
+
+        example "once" do
+          expect(logger).to receive(:account_opened).once
+          account.open
+        end
+
+        example "twice" do
+          expect(logger).to receive(:account_opened).twice
+          account.open
+          account.open
+        end
+
+        example "exactly(n).times" do
+          expect(logger).to receive(:account_opened).exactly(3).times
+          account.open
+          account.open
+          account.open
+        end
+
+        example "at_least(:once)" do
+          expect(logger).to receive(:account_opened).at_least(:once)
+          account.open
+          account.open
+        end
+
+        example "at_least(:twice)" do
+          expect(logger).to receive(:account_opened).at_least(:twice)
+          account.open
+          account.open
+          account.open
+        end
+
+        example "at_least(n).times" do
+          expect(logger).to receive(:account_opened).at_least(3).times
+          account.open
+          account.open
+          account.open
+          account.open
+        end
+
+        example "at_most(:once)" do
+          expect(logger).to receive(:account_opened).at_most(:once)
+        end
+
+        example "at_most(:twice)" do
+          expect(logger).to receive(:account_opened).at_most(:twice)
+          account.open
+        end
+
+        example "at_most(n).times" do
+          expect(logger).to receive(:account_opened).at_most(3).times
+          account.open
+          account.open
+        end
+      end
+      """
+    When I run `rspec spec/account_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Failing examples
+    Given a file named "spec/account_spec.rb" with:
+      """ruby
+      require 'account'
+
+      RSpec.describe Account do
+        let(:logger)  { double("Logger") }
+        let(:account) { Account.new(logger) }
+
+        example "once" do
+          expect(logger).to receive(:account_opened).once
+          account.open
+          account.open
+        end
+
+        example "twice" do
+          expect(logger).to receive(:account_opened).twice
+          account.open
+        end
+
+        example "exactly(n).times" do
+          expect(logger).to receive(:account_opened).exactly(3).times
+          account.open
+          account.open
+        end
+
+        example "at_least(:once)" do
+          expect(logger).to receive(:account_opened).at_least(:once)
+        end
+
+        example "at_least(:twice)" do
+          expect(logger).to receive(:account_opened).at_least(:twice)
+          account.open
+        end
+
+        example "at_least(n).times" do
+          expect(logger).to receive(:account_opened).at_least(3).times
+          account.open
+          account.open
+        end
+
+        example "at_most(:once)" do
+          expect(logger).to receive(:account_opened).at_most(:once)
+          account.open
+          account.open
+        end
+
+        example "at_most(:twice)" do
+          expect(logger).to receive(:account_opened).at_most(:twice)
+          account.open
+          account.open
+          account.open
+        end
+
+        example "at_most(n).times" do
+          expect(logger).to receive(:account_opened).at_most(3).times
+          account.open
+          account.open
+          account.open
+          account.open
+        end
+      end
+      """
+    When I run `rspec spec/account_spec.rb --order defined`
+    Then the examples should all fail, producing the following output:
+      | expected: 1 time with any arguments           |
+      | received: 2 times                             |
+      |                                               |
+      | expected: 2 times with any arguments          |
+      | received: 1 time with any arguments           |
+      |                                               |
+      | expected: 3 times with any arguments          |
+      | received: 2 times with any arguments          |
+      |                                               |
+      | expected: at least 1 time with any arguments  |
+      | received: 0 times with any arguments          |
+      |                                               |
+      | expected: at least 2 times with any arguments |
+      | received: 1 time with any arguments           |
+      |                                               |
+      | expected: at least 3 times with any arguments |
+      | received: 2 times with any arguments          |
+      |                                               |
+      | expected: at most 1 time with any arguments   |
+      | received: 2 times                             |
+      |                                               |
+      | expected: at most 2 times with any arguments  |
+      | received: 3 times                             |
+      |                                               |
+      | expected: at most 3 times with any arguments  |
+      | received: 4 times                             |
diff --git a/rspec-mocks/features/step_definitions/additional_cli_steps.rb b/rspec-mocks/features/step_definitions/additional_cli_steps.rb
new file mode 100644
index 0000000..d9f3f70
--- /dev/null
+++ b/rspec-mocks/features/step_definitions/additional_cli_steps.rb
@@ -0,0 +1,21 @@
+Then /^the example(?:s)? should(?: all)? pass$/ do
+  step %q{the output should contain "0 failures"}
+  step %q{the exit status should be 0}
+end
+
+Then /^the examples should all fail, producing the following output:$/ do |table|
+  step %q{the exit status should be 1}
+  examples, failures = all_output.match(/(\d+) examples?, (\d+) failures?/).captures.map(&:to_i)
+
+  expect(examples).to be > 0
+  expect(examples).to eq(failures)
+
+  lines = table.raw.flatten.reject(&:empty?)
+  expect(all_output).to include(*lines)
+end
+
+Then /^it should fail with the following output:$/ do |table|
+  step %q{the exit status should be 1}
+  lines = table.raw.flatten.reject(&:empty?)
+  expect(all_output).to include(*lines)
+end
diff --git a/rspec-mocks/features/support/disallow_certain_apis.rb b/rspec-mocks/features/support/disallow_certain_apis.rb
new file mode 100644
index 0000000..08b93b4
--- /dev/null
+++ b/rspec-mocks/features/support/disallow_certain_apis.rb
@@ -0,0 +1,24 @@
+# This file is designed to prevent the use of certain APIs that
+# we don't want used from our cukes, since they function as documentation.
+
+if defined?(Cucumber)
+  require 'shellwords'
+  Before('~@allow-old-syntax') do
+    set_env('SPEC_OPTS', "-r#{Shellwords.escape(__FILE__)}")
+  end
+else
+  module DisallowOneLinerShould
+    def should(*)
+      raise "one-liner should is not allowed"
+    end
+
+    def should_not(*)
+      raise "one-liner should_not is not allowed"
+    end
+  end
+
+  RSpec.configure do |rspec|
+    rspec.disable_monkey_patching!
+    rspec.include DisallowOneLinerShould
+  end
+end
diff --git a/rspec-mocks/features/support/env.rb b/rspec-mocks/features/support/env.rb
new file mode 100644
index 0000000..21420d4
--- /dev/null
+++ b/rspec-mocks/features/support/env.rb
@@ -0,0 +1,22 @@
+require 'aruba/cucumber'
+require 'rspec/expectations'
+
+Before do
+  if RUBY_PLATFORM =~ /java/ || defined?(Rubinius)
+    @aruba_timeout_seconds = 60
+  else
+    @aruba_timeout_seconds = 5
+  end
+end
+
+Aruba.configure do |config|
+  config.before_cmd do |cmd|
+    set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
+  end
+end if RUBY_PLATFORM == 'java'
+
+Aruba.configure do |config|
+  config.before_cmd do |cmd|
+    set_env('RBXOPT', "-Xint=true #{ENV['RBXOPT']}") # disable JIT since these processes are so short lived
+  end
+end if defined?(Rubinius)
diff --git a/rspec-mocks/features/support/rubinius.rb b/rspec-mocks/features/support/rubinius.rb
new file mode 100644
index 0000000..3907962
--- /dev/null
+++ b/rspec-mocks/features/support/rubinius.rb
@@ -0,0 +1,6 @@
+# Required until https://github.com/rubinius/rubinius/issues/2430 is resolved
+ENV['RBXOPT'] = "#{ENV["RBXOPT"]} -Xcompiler.no_rbc"
+
+Around "@unsupported-on-rbx" do |scenario, block|
+  block.call unless defined?(Rubinius)
+end
diff --git a/rspec-mocks/features/verifying_doubles/README.md b/rspec-mocks/features/verifying_doubles/README.md
new file mode 100644
index 0000000..d27acac
--- /dev/null
+++ b/rspec-mocks/features/verifying_doubles/README.md
@@ -0,0 +1,13 @@
+Verifying doubles are a stricter alternative to [normal doubles](./basics/test-doubles) that provide guarantees about
+what is being verified. When using verifying doubles, RSpec will check that the methods
+being stubbed are actually present on the underlying object if it is available. Prefer using
+verifying doubles over normal doubles.
+
+No checking will happen if the underlying object or class is not defined, but when run with
+it present (either as a full spec run or by explicitly preloading collaborators) a failure will be
+triggered if an invalid method is being stubbed or a method is called with an invalid
+number of arguments.
+
+This dual approach allows you to move very quickly and test components in isolation, while
+giving you confidence that your doubles are not a complete fiction. Testing in isolation is
+optional but recommend for classes that do not depend on third-party components.
diff --git a/rspec-mocks/features/verifying_doubles/class_doubles.feature b/rspec-mocks/features/verifying_doubles/class_doubles.feature
new file mode 100644
index 0000000..8c94cd7
--- /dev/null
+++ b/rspec-mocks/features/verifying_doubles/class_doubles.feature
@@ -0,0 +1,70 @@
+Feature: Using a class double
+
+  `class_double` is provided as a complement to [`instance_double`](./using-an-instance-double) with the difference that it
+  verifies _class_ methods on the given class rather than instance methods.
+
+  In addition, it also provides a convenience method `as_stubbed_const` to replace concrete
+  classes with the defined double. See [mutating constants](../mutating-constants) for more details.
+
+  Note: `class_double` can be used for modules as well. We chose to stick with the
+  `class_double` terminology because the methods a `class_double` verifies against are
+  commonly called "class methods", not "module methods", even when working with a module.
+
+  Background:
+    Given a file named "lib/user.rb" with:
+      """ruby
+      class User
+        def suspend!
+          ConsoleNotifier.notify("suspended as")
+        end
+      end
+      """
+
+    Given a file named "lib/console_notifier.rb" with:
+      """ruby
+      class ConsoleNotifier
+        MAX_WIDTH = 80
+
+        def self.notify(message)
+          puts message
+        end
+      end
+      """
+
+    Given a file named "spec/user_spec.rb" with:
+      """ruby
+      require 'user'
+      require 'console_notifier'
+
+      RSpec.describe User, '#suspend!' do
+        it 'notifies the console' do
+          notifier = class_double("ConsoleNotifier").
+            as_stubbed_const(:transfer_nested_constants => true)
+
+          expect(notifier).to receive(:notify).with("suspended as")
+          expect(ConsoleNotifier::MAX_WIDTH).to eq(80)
+
+          user = User.new
+          user.suspend!
+        end
+      end
+      """
+
+  Scenario: replacing existing constants
+    When I run `rspec spec/user_spec.rb`
+    Then the examples should all pass
+
+  Scenario: renaming `ConsoleNotifier.notify` to `send_notification`
+    Given a file named "lib/console_notifier.rb" with:
+      """ruby
+      class ConsoleNotifier
+        MAX_WIDTH = 80
+
+        def self.send_notification(message)
+          puts message
+        end
+      end
+      """
+    When I run `rspec spec/user_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "ConsoleNotifier does not implement:"
diff --git a/rspec-mocks/features/verifying_doubles/dynamic_classes.feature b/rspec-mocks/features/verifying_doubles/dynamic_classes.feature
new file mode 100644
index 0000000..e7b52fc
--- /dev/null
+++ b/rspec-mocks/features/verifying_doubles/dynamic_classes.feature
@@ -0,0 +1,110 @@
+Feature: Dynamic classes
+
+  Verifying instance doubles do not support methods which the class reports to not exist
+  since an actual instance of the class would be required to verify against. This is commonly
+  the case when `method_missing` is used.
+
+  There are a few ways to work around this. If the object has already been loaded you may
+  consider using an [`object_double`](./using-an-object-double), but that cannot work if you
+  are testing in isolation. Alternatively you could implement the methods directly (calling
+  `super` to return the `method_missing` definition).
+
+  Some of these classes may have methods to define these methods on the objects at runtime.
+  (For example, `ActiveRecord` does this to define methods from database columns.) For these
+  cases we provide an API which can be used to customise verifying doubles on creation. We
+  use this ourselves in `rspec-rails` to set up some niceties for you.
+
+  These types of methods are supported at class level (with `class_double`) however, since
+  `respond_to?` can be queried directly on the class.
+
+  Background:
+    Given a file named "lib/fake_active_record.rb" with:
+      """ruby
+      class FakeActiveRecord
+        COLUMNS = %w[name email]
+
+        def respond_to_missing?(method_name)
+          COLUMNS.include?(method_name.to_s) || super
+        end
+
+        def method_missing(method_name, *args)
+          if respond_to?(method_name)
+            instance_variable_get("@#{method_name}")
+          else
+            super
+          end
+        end
+
+        def self.define_attribute_methods
+          COLUMNS.each do |name|
+            define_method(name) { instance_variable_get("@#{name}") }
+          end
+        end
+      end
+      """
+
+    Given a file named "spec/user_spec.rb" with:
+      """ruby
+      require 'user'
+
+      RSpec.describe User do
+        it 'can be doubled' do
+          instance_double("User", :name => "Don")
+        end
+      end
+      """
+
+  Scenario: fails with method missing
+
+    Given a file named "lib/user.rb" with:
+      """ruby
+      require 'fake_active_record'
+
+      class User < FakeActiveRecord
+      end
+      """
+
+    When I run `rspec spec/user_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+
+  Scenario: workaround with explict definitions
+
+    Given a file named "lib/user.rb" with:
+      """ruby
+      require 'fake_active_record'
+
+      class User < FakeActiveRecord
+        def name;  super end
+        def email; super end
+      end
+      """
+
+    When I run `rspec spec/user_spec.rb`
+    Then the examples should all pass
+
+  Scenario: workaround using callback
+
+    Given a file named "lib/user.rb" with:
+      """ruby
+      require 'fake_active_record'
+
+      class User < FakeActiveRecord
+      end
+      """
+    And a file named "spec/fake_record_helper.rb" with:
+      """ruby
+      RSpec.configuration.mock_with(:rspec) do |config|
+        config.when_declaring_verifying_double do |reference|
+          reference.target.define_attribute_methods
+        end
+      end
+      #
+      # or you can use:
+      #
+      # RSpec::Mocks.configuration.when_declaring_verifying_double do |refernece|
+      #   reference.target.define_attribute_methods
+      # end
+      """
+
+    When I run `rspec -r fake_record_helper spec/user_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/verifying_doubles/instance_doubles.feature b/rspec-mocks/features/verifying_doubles/instance_doubles.feature
new file mode 100644
index 0000000..c234ca0
--- /dev/null
+++ b/rspec-mocks/features/verifying_doubles/instance_doubles.feature
@@ -0,0 +1,103 @@
+Feature: Using an instance double
+
+  An `instance_double` is the most common type of verifying double. It takes a class name or
+  object as its first argument, then verifies that any methods being stubbed would be present
+  on an _instance_ of that class. In addition, when it receives messages, it verifies that the
+  provided arguments are supported by the method signature, both in terms of arity and
+  allowed or required keyword arguments, if any. The same argument verification happens
+  when you [constrain the arguments](../setting-constraints/matching-arguments) using `with`.
+
+  For methods handled by `method_missing`, see [dynamic classes](./dynamic-classes).
+
+  Background:
+    Given a file named "app/models/user.rb" with:
+      """ruby
+      class User < Struct.new(:notifier)
+        def suspend!
+          notifier.notify("suspended as")
+        end
+      end
+      """
+
+    Given a file named "spec/unit_helper.rb" with:
+      """ruby
+      $LOAD_PATH.unshift("app/models")
+      """
+
+    Given a file named "spec/spec_helper.rb" with:
+      """ruby
+      require 'unit_helper'
+
+      require 'user'
+      require 'console_notifier'
+
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+
+          # This option should be set when all dependencies are being loaded
+          # before a spec run, as is the case in a typical spec helper. It will
+          # cause any verifying double instantiation for a class that does not
+          # exist to raise, protecting against incorrectly spelt names.
+          mocks.verify_doubled_constant_names = true
+
+        end
+      end
+      """
+
+    Given a file named "spec/unit/user_spec.rb" with:
+      """ruby
+      require 'unit_helper'
+
+      require 'user'
+
+      RSpec.describe User, '#suspend!' do
+        it 'notifies the console' do
+          notifier = instance_double("ConsoleNotifier")
+
+          expect(notifier).to receive(:notify).with("suspended as")
+
+          user = User.new(notifier)
+          user.suspend!
+        end
+      end
+      """
+
+  Scenario: spec passes in isolation
+    When I run `rspec spec/unit/user_spec.rb`
+    Then the examples should all pass
+
+  Scenario: spec passes with dependencies loaded and method implemented
+    Given a file named "app/models/console_notifier.rb" with:
+      """ruby
+      class ConsoleNotifier
+        def notify(msg)
+          puts message
+        end
+      end
+      """
+
+    When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
+    Then the examples should all pass
+
+  Scenario: spec fails with dependencies loaded and method unimplemented
+    Given a file named "app/models/console_notifier.rb" with:
+      """ruby
+      class ConsoleNotifier
+      end
+      """
+    When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "ConsoleNotifier does not implement:"
+
+  Scenario: spec fails with dependencies loaded and incorrect arity
+    Given a file named "app/models/console_notifier.rb" with:
+      """ruby
+      class ConsoleNotifier
+        def notify(msg, color)
+          puts color + message
+        end
+      end
+      """
+    When I run `rspec -r./spec/spec_helper spec/unit/user_spec.rb`
+    Then the output should contain "1 example, 1 failure"
+    And the output should contain "Wrong number of arguments."
diff --git a/rspec-mocks/features/verifying_doubles/object_doubles.feature b/rspec-mocks/features/verifying_doubles/object_doubles.feature
new file mode 100644
index 0000000..776a288
--- /dev/null
+++ b/rspec-mocks/features/verifying_doubles/object_doubles.feature
@@ -0,0 +1,62 @@
+Feature: Using an object double
+
+  `object_double` can be used to create a double from an existing "template" object, from
+  which it verifies that any stubbed methods on the double also exist on the template. This is
+  useful for objects that are readily constructable, but may have far-reaching side-effects
+  such as talking to a database or external API. In this case, using a double rather than the
+  real thing allows you to focus on the communication patterns of the object's interface
+  without having to worry about accidentally causing side-effects. Object doubles can also be
+  used to verify methods defined on an object using `method_missing`, which is not possible
+  with [`instance_double`](./using-an-instance-double).
+
+  In addition, `object_double` can be used with specific constant values, as shown below. This
+  is for niche situations, such as when dealing with singleton objects.
+
+  Scenario: doubling an existing object
+    Given a file named "spec/user_spec.rb" with:
+      """ruby
+      class User
+        # Don't want to accidentally trigger this!
+        def save; sleep 100; end
+      end
+
+      def save_user(user)
+        "saved!" if user.save
+      end
+
+      RSpec.describe '#save_user' do
+        it 'renders message on success' do
+          user = object_double(User.new, :save => true)
+          expect(save_user(user)).to eq("saved!")
+        end
+      end
+      """
+    When I run `rspec spec/user_spec.rb`
+    Then the examples should all pass
+
+  Scenario: doubling a constant object
+    Given a file named "spec/email_spec.rb" with:
+      """ruby
+      require 'logger'
+
+      module MyApp
+        LOGGER = Logger.new("myapp")
+      end
+
+      class Email
+        def self.send_to(recipient)
+          MyApp::LOGGER.info("Sent to #{recipient}")
+          # other emailing logic
+        end
+      end
+
+      RSpec.describe Email do
+        it 'logs a message when sending' do
+          logger = object_double("MyApp::LOGGER", :info => nil).as_stubbed_const
+          Email.send_to('hello at foo.com')
+          expect(logger).to have_received(:info).with("Sent to hello at foo.com")
+        end
+      end
+      """
+    When I run `rspec spec/email_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/features/verifying_doubles/partial_doubles.feature b/rspec-mocks/features/verifying_doubles/partial_doubles.feature
new file mode 100644
index 0000000..4dadd03
--- /dev/null
+++ b/rspec-mocks/features/verifying_doubles/partial_doubles.feature
@@ -0,0 +1,34 @@
+Feature: Partial doubles
+
+  When the `verify_partial_doubles` configuration option is set, the same argument and
+  method existence checks that are performed for [`object_double`](./using-an-object-double) are also performed on
+  [partial doubles](../basics/partial-test-doubles). You should set this unless you have a good reason not to. It defaults to off
+  only for backwards compatibility.
+
+  Scenario: doubling an existing object
+    Given a file named "spec/user_spec.rb" with:
+      """ruby
+      class User
+        def save; false; end
+      end
+
+      def save_user(user)
+        "saved!" if user.save
+      end
+
+      RSpec.configure do |config|
+        config.mock_with :rspec do |mocks|
+          mocks.verify_partial_doubles = true
+        end
+      end
+
+      RSpec.describe '#save_user' do
+        it 'renders message on success' do
+          user = User.new
+          expect(user).to receive(:saave).and_return(true) # Typo in name
+          expect(save_user(user)).to eq("saved!")
+        end
+      end
+      """
+    When I run `rspec spec/user_spec.rb`
+    Then the output should contain "1 example, 1 failure"
diff --git a/rspec-mocks/features/working_with_legacy_code/README.md b/rspec-mocks/features/working_with_legacy_code/README.md
new file mode 100644
index 0000000..862f15a
--- /dev/null
+++ b/rspec-mocks/features/working_with_legacy_code/README.md
@@ -0,0 +1,3 @@
+RSpec provides a few features that, while not generally recommended, can be useful when
+you are getting legacy code under test (or in similar situations). Usage of these features
+should be considered a code smell.
diff --git a/rspec-mocks/features/working_with_legacy_code/any_instance.feature b/rspec-mocks/features/working_with_legacy_code/any_instance.feature
new file mode 100644
index 0000000..1b58a2d
--- /dev/null
+++ b/rspec-mocks/features/working_with_legacy_code/any_instance.feature
@@ -0,0 +1,115 @@
+Feature: Any Instance
+
+  rspec-mocks provides two methods, `allow_any_instance_of` and
+  `expect_any_instance_of`, that will allow you to stub or mock any instance of a class. They
+  are used in place of [`allow`](../basics/allowing-messages) or [`expect`](../basics/expecting-messages):
+
+  ```ruby
+  allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
+  expect_any_instance_of(Widget).to receive(:name).and_return("Wobble")
+  ```
+
+  These methods add the appropriate stub or expectation to all instances of `Widget`.
+
+  This feature is sometimes useful when working with legacy code, though in general we
+  discourage its use for a number of reasons:
+
+  * The `rspec-mocks` API is designed for individual object instances, but this feature
+    operates on entire classes of objects. As a result there are some semantically confusing
+    edge cases. For example, in `expect_any_instance_of(Widget).to
+    receive(:name).twice` it isn't clear whether each specific instance is expected to
+    receive `name` twice, or if two receives total are expected. (It's the former.)
+  * Using this feature is often a design smell. It may be that your test is trying to do too
+    much or that the object under test is too complex.
+  * It is the most complicated feature of `rspec-mocks`, and has historically received the
+    most bug reports. (None of the core team actively use it, which doesn't help.)
+
+  Scenario: Use `allow_any_instance_of` to stub a method
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "allow_any_instance_of" do
+        it "returns the specified value on any instance of the class" do
+          allow_any_instance_of(Object).to receive(:foo).and_return(:return_value)
+
+          o = Object.new
+          expect(o.foo).to eq(:return_value)
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `allow_any_instance_of` to stub multiple methods
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "allow_any_instance_of" do
+        context "with receive_messages" do
+          it "stubs multiple methods" do
+            allow_any_instance_of(Object).to receive_messages(:foo => 'foo', :bar => 'bar')
+
+            o = Object.new
+            expect(o.foo).to eq('foo')
+            expect(o.bar).to eq('bar')
+          end
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Stubbing any instance of a class with specific arguments
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "allow_any_instance_of" do
+        context "with arguments" do
+          it "returns the stubbed value when arguments match" do
+            allow_any_instance_of(Object).to receive(:foo).with(:param_one, :param_two).and_return(:result_one)
+            allow_any_instance_of(Object).to receive(:foo).with(:param_three, :param_four).and_return(:result_two)
+
+            o = Object.new
+            expect(o.foo(:param_one, :param_two)).to eq(:result_one)
+            expect(o.foo(:param_three, :param_four)).to eq(:result_two)
+          end
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Block implementation is passed the receiver as first arg
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "allow_any_instance_of" do
+        it 'yields the receiver to the block implementation' do
+          allow_any_instance_of(String).to receive(:slice) do |value, start, length|
+            value[start, length]
+          end
+
+          expect('string'.slice(2, 3)).to eq('rin')
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `expect_any_instance_of` to set a message expectation on any instance
+    Given a file named "example_spec.rb" with:
+      """ruby
+      RSpec.describe "expect_any_instance_of" do
+        before do
+          expect_any_instance_of(Object).to receive(:foo)
+        end
+
+        it "passes when an instance receives the message" do
+          Object.new.foo
+        end
+
+        it "fails when no instance receives the message" do
+          Object.new.to_s
+        end
+      end
+      """
+    When I run `rspec example_spec.rb`
+    Then it should fail with the following output:
+      | 2 examples, 1 failure |
+      | Exactly one instance should have received the following message(s) but didn't: foo |
diff --git a/rspec-mocks/features/working_with_legacy_code/message_chains.feature b/rspec-mocks/features/working_with_legacy_code/message_chains.feature
new file mode 100644
index 0000000..1627dc9
--- /dev/null
+++ b/rspec-mocks/features/working_with_legacy_code/message_chains.feature
@@ -0,0 +1,79 @@
+Feature: Message Chains
+
+  You can use `receive_message_chain` in place of `receive` to stub a chain of messages:
+
+  ```ruby
+  allow(double).to receive_message_chain("foo.bar") { :baz }
+  allow(double).to receive_message_chain(:foo, :bar => :baz)
+  allow(double).to receive_message_chain(:foo, :bar) { :baz }
+  ````
+
+  Given any of these three forms:
+
+  ```ruby
+  double.foo.bar # => :baz
+  ```
+
+  Common use in Rails/ActiveRecord:
+
+  ```ruby
+  allow(Article).to receive_message_chain("recent.published") { [Article.new] }
+  ```
+
+  Warning:
+  ========
+
+  Chains can be arbitrarily long, which makes it quite painless to violate the Law of Demeter
+  in violent ways, so you should consider any use of `receive_message_chain` a code smell.
+  Even though not all code smells indicate real problems (think fluent interfaces),
+  `receive_message_chain` still results in brittle examples. For example, if you write
+  `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the
+  implementation calls `foo.baz.bar`, the stub will not work.
+
+  Scenario: Use `receive_message_chain` on a double
+    Given a file named "receive_message_chain_spec.rb" with:
+      """ruby
+      RSpec.describe "Using receive_message_chain on a double" do
+        let(:dbl) { double }
+
+        example "using a string and a block" do
+          allow(dbl).to receive_message_chain("foo.bar") { :baz }
+          expect(dbl.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a hash" do
+          allow(dbl).to receive_message_chain(:foo, :bar => :baz)
+          expect(dbl.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a block" do
+          allow(dbl).to receive_message_chain(:foo, :bar) { :baz }
+          expect(dbl.foo.bar).to eq(:baz)
+        end
+      end
+      """
+    When I run `rspec receive_message_chain_spec.rb`
+    Then the examples should all pass
+
+  Scenario: Use `receive_message_chain` on any instance of a class
+    Given a file named "receive_message_chain_spec.rb" with:
+      """ruby
+      RSpec.describe "Using receive_message_chain on any instance of a class" do
+        example "using a string and a block" do
+          allow_any_instance_of(Object).to receive_message_chain("foo.bar") { :baz }
+          expect(Object.new.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a hash" do
+          allow_any_instance_of(Object).to receive_message_chain(:foo, :bar => :baz)
+          expect(Object.new.foo.bar).to eq(:baz)
+        end
+
+        example "using symbols and a block" do
+          allow_any_instance_of(Object).to receive_message_chain(:foo, :bar) { :baz }
+          expect(Object.new.foo.bar).to eq(:baz)
+        end
+      end
+      """
+    When I run `rspec receive_message_chain_spec.rb`
+    Then the examples should all pass
diff --git a/rspec-mocks/lib/rspec/mocks.rb b/rspec-mocks/lib/rspec/mocks.rb
new file mode 100644
index 0000000..17b2831
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks.rb
@@ -0,0 +1,126 @@
+require 'rspec/support'
+RSpec::Support.require_rspec_support 'caller_filter'
+RSpec::Support.require_rspec_support 'warnings'
+RSpec::Support.require_rspec_support 'ruby_features'
+
+RSpec::Support.define_optimized_require_for_rspec(:mocks) { |f| require_relative f }
+
+%w[
+  instance_method_stasher
+  method_double
+  argument_matchers
+  example_methods
+  proxy
+  test_double
+  argument_list_matcher
+  message_expectation
+  order_group
+  error_generator
+  space
+  mutate_const
+  targets
+  syntax
+  configuration
+  verifying_double
+  version
+].each { |name| RSpec::Support.require_rspec_mocks name }
+
+# Share the top-level RSpec namespace, because we are a core supported
+# extension.
+module RSpec
+  # Contains top-level utility methods. While this contains a few
+  # public methods, these are not generally meant to be called from
+  # a test or example. They exist primarily for integration with
+  # test frameworks (such as rspec-core).
+  module Mocks
+    # Performs per-test/example setup. This should be called before
+    # an test or example begins.
+    def self.setup
+      @space_stack << (@space = space.new_scope)
+    end
+
+    # Verifies any message expectations that were set during the
+    # test or example. This should be called at the end of an example.
+    def self.verify
+      space.verify_all
+    end
+
+    # Cleans up all test double state (including any methods that were
+    # redefined on partial doubles). This _must_ be called after
+    # each example, even if an error was raised during the example.
+    def self.teardown
+      space.reset_all
+      @space_stack.pop
+      @space = @space_stack.last || @root_space
+    end
+
+    # Adds an allowance (stub) on `subject`
+    #
+    # @param subject the subject to which the message will be added
+    # @param message a symbol, representing the message that will be
+    #                added.
+    # @param opts a hash of options, :expected_from is used to set the
+    #             original call site
+    # @yield an optional implementation for the allowance
+    #
+    # @example Defines the implementation of `foo` on `bar`, using the passed block
+    #   x = 0
+    #   RSpec::Mocks.allow_message(bar, :foo) { x += 1 }
+    def self.allow_message(subject, message, opts={}, &block)
+      space.proxy_for(subject).add_stub(message, opts, &block)
+    end
+
+    # Sets a message expectation on `subject`.
+    # @param subject the subject on which the message will be expected
+    # @param message a symbol, representing the message that will be
+    #                expected.
+    # @param opts a hash of options, :expected_from is used to set the
+    #             original call site
+    # @yield an optional implementation for the expectation
+    #
+    # @example Expect the message `foo` to receive `bar`, then call it
+    #   RSpec::Mocks.expect_message(bar, :foo)
+    #   bar.foo
+    def self.expect_message(subject, message, opts={}, &block)
+      space.proxy_for(subject).add_message_expectation(message, opts, &block)
+    end
+
+    # Call the passed block and verify mocks after it has executed. This allows
+    # mock usage in arbitrary places, such as a `before(:all)` hook.
+    def self.with_temporary_scope
+      setup
+
+      begin
+        yield
+        verify
+      ensure
+        teardown
+      end
+    end
+
+    class << self
+      # @private
+      attr_reader :space
+    end
+    @space_stack = []
+    @root_space  = @space = RSpec::Mocks::RootSpace.new
+
+    # @private
+    IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored'
+
+    # To speed up boot time a bit, delay loading optional or rarely
+    # used features until their first use.
+    autoload :AnyInstance,      "rspec/mocks/any_instance"
+    autoload :ExpectChain,      "rspec/mocks/message_chain"
+    autoload :StubChain,        "rspec/mocks/message_chain"
+    autoload :MarshalExtension, "rspec/mocks/marshal_extension"
+
+    # Namespace for mock-related matchers.
+    module Matchers
+      autoload :HaveReceived,        "rspec/mocks/matchers/have_received"
+      autoload :Receive,             "rspec/mocks/matchers/receive"
+      autoload :ReceiveMessageChain, "rspec/mocks/matchers/receive_message_chain"
+      autoload :ReceiveMessages,     "rspec/mocks/matchers/receive_messages"
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance.rb b/rspec-mocks/lib/rspec/mocks/any_instance.rb
new file mode 100644
index 0000000..bc912d8
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance.rb
@@ -0,0 +1,10 @@
+%w[
+  any_instance/chain
+  any_instance/stub_chain
+  any_instance/stub_chain_chain
+  any_instance/expect_chain_chain
+  any_instance/expectation_chain
+  any_instance/message_chains
+  any_instance/recorder
+  any_instance/proxy
+].each { |f| RSpec::Support.require_rspec_mocks(f) }
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/chain.rb b/rspec-mocks/lib/rspec/mocks/any_instance/chain.rb
new file mode 100644
index 0000000..db9d618
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/chain.rb
@@ -0,0 +1,110 @@
+module RSpec
+  module Mocks
+    # @private
+    module AnyInstance
+      # @private
+      class Chain
+        def initialize(recorder, *args, &block)
+          @recorder          = recorder
+          @expectation_args  = args
+          @expectation_block = block
+          @argument_list_matcher = ArgumentListMatcher::MATCH_ALL
+        end
+
+        # @private
+        #
+        # Provides convenience methods for recording customizations on message
+        # expectations.
+        module Customizations
+          # @macro [attach] record
+          #   @method $1(*args, &block)
+          #   Records the `$1` message for playback against an instance that
+          #   invokes a method stubbed or mocked using `any_instance`.
+          #
+          #   @see RSpec::Mocks::MessageExpectation#$1
+          #
+          def self.record(method_name)
+            define_method(method_name) do |*args, &block|
+              record(method_name, *args, &block)
+            end
+          end
+
+          record :and_return
+          record :and_raise
+          record :and_throw
+          record :and_yield
+          record :and_call_original
+          record :and_wrap_original
+          record :with
+          record :once
+          record :twice
+          record :thrice
+          record :exactly
+          record :times
+          record :never
+          record :at_least
+          record :at_most
+        end
+
+        include Customizations
+
+        # @private
+        def playback!(instance)
+          message_expectation = create_message_expectation_on(instance)
+          messages.inject(message_expectation) do |object, message|
+            object.__send__(*message.first, &message.last)
+          end
+        end
+
+        # @private
+        def constrained_to_any_of?(*constraints)
+          constraints.any? do |constraint|
+            messages.any? do |message|
+              message.first.first == constraint
+            end
+          end
+        end
+
+        # @private
+        def matches_args?(*args)
+          @argument_list_matcher.args_match?(*args)
+        end
+
+        # @private
+        def expectation_fulfilled!
+          @expectation_fulfilled = true
+        end
+
+        def never
+          ErrorGenerator.raise_double_negation_error("expect_any_instance_of(MyClass)") if negated?
+          super
+        end
+
+        def with(*args, &block)
+          @argument_list_matcher = ArgumentListMatcher.new(*args)
+          super
+        end
+
+      private
+
+        def negated?
+          messages.any? { |(message, *_), _| message == :never }
+        end
+
+        def messages
+          @messages ||= []
+        end
+
+        def last_message
+          messages.last.first.first unless messages.empty?
+        end
+
+        def record(rspec_method_name, *args, &block)
+          verify_invocation_order(rspec_method_name, *args, &block)
+          messages << [args.unshift(rspec_method_name), block]
+          self
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/expect_chain_chain.rb b/rspec-mocks/lib/rspec/mocks/any_instance/expect_chain_chain.rb
new file mode 100644
index 0000000..0d13402
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/expect_chain_chain.rb
@@ -0,0 +1,35 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # @private
+      class ExpectChainChain < StubChain
+        def initialize(*args)
+          super
+          @expectation_fulfilled = false
+        end
+
+        def expectation_fulfilled?
+          @expectation_fulfilled
+        end
+
+        def playback!(instance)
+          super.tap { @expectation_fulfilled = true }
+        end
+
+      private
+
+        def create_message_expectation_on(instance)
+          ::RSpec::Mocks::ExpectChain.expect_chain_on(instance, *@expectation_args, &@expectation_block)
+        end
+
+        def invocation_order
+          @invocation_order ||= {
+            :and_return => [nil],
+            :and_raise => [nil],
+            :and_yield => [nil]
+          }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/expectation_chain.rb b/rspec-mocks/lib/rspec/mocks/any_instance/expectation_chain.rb
new file mode 100644
index 0000000..02b55e8
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/expectation_chain.rb
@@ -0,0 +1,48 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # @private
+      class ExpectationChain < Chain
+        def expectation_fulfilled?
+          @expectation_fulfilled || constrained_to_any_of?(:never)
+        end
+
+        def initialize(*args, &block)
+          @expectation_fulfilled = false
+          super
+        end
+
+      private
+
+        def verify_invocation_order(_rspec_method_name, *_args, &_block)
+        end
+      end
+
+      # @private
+      class PositiveExpectationChain < ExpectationChain
+      private
+
+        def create_message_expectation_on(instance)
+          proxy = ::RSpec::Mocks.space.proxy_for(instance)
+          method_name, opts = @expectation_args
+          opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE)
+
+          me = proxy.add_message_expectation(method_name, opts, &@expectation_block)
+          if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks?
+            me.and_yield_receiver_to_implementation
+          end
+
+          me
+        end
+
+        def invocation_order
+          @invocation_order ||= {
+            :with => [nil],
+            :and_return => [:with, nil],
+            :and_raise => [:with, nil]
+          }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/message_chains.rb b/rspec-mocks/lib/rspec/mocks/any_instance/message_chains.rb
new file mode 100644
index 0000000..0ce39bc
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/message_chains.rb
@@ -0,0 +1,85 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # @private
+      class MessageChains
+        def initialize
+          @chains_by_method_name = Hash.new { |h, k| h[k] = [] }
+        end
+
+        # @private
+        def [](method_name)
+          @chains_by_method_name[method_name]
+        end
+
+        # @private
+        def add(method_name, chain)
+          @chains_by_method_name[method_name] << chain
+          chain
+        end
+
+        # @private
+        def remove_stub_chains_for!(method_name)
+          @chains_by_method_name[method_name].reject! do |chain|
+            StubChain === chain
+          end
+        end
+
+        # @private
+        def has_expectation?(method_name)
+          @chains_by_method_name[method_name].find do |chain|
+            ExpectationChain === chain
+          end
+        end
+
+        # @private
+        def each_unfulfilled_expectation_matching(method_name, *args)
+          @chains_by_method_name[method_name].each do |chain|
+            yield chain if !chain.expectation_fulfilled? && chain.matches_args?(*args)
+          end
+        end
+
+        # @private
+        def all_expectations_fulfilled?
+          @chains_by_method_name.all? do |_method_name, chains|
+            chains.all? { |chain| chain.expectation_fulfilled? }
+          end
+        end
+
+        # @private
+        def unfulfilled_expectations
+          @chains_by_method_name.map do |method_name, chains|
+            method_name.to_s if ExpectationChain === chains.last unless chains.last.expectation_fulfilled?
+          end.compact
+        end
+
+        # @private
+        def received_expected_message!(method_name)
+          @chains_by_method_name[method_name].each do |chain|
+            chain.expectation_fulfilled!
+          end
+        end
+
+        # @private
+        def playback!(instance, method_name)
+          raise_if_second_instance_to_receive_message(instance)
+          @chains_by_method_name[method_name].each do |chain|
+            chain.playback!(instance)
+          end
+        end
+
+      private
+
+        def raise_if_second_instance_to_receive_message(instance)
+          @instance_with_expectation ||= instance if ExpectationChain === instance
+          return unless ExpectationChain === instance
+          return if @instance_with_expectation.equal?(instance)
+
+          raise RSpec::Mocks::MockExpectationError,
+                "Exactly one instance should have received the following " \
+                "message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/proxy.rb b/rspec-mocks/lib/rspec/mocks/any_instance/proxy.rb
new file mode 100644
index 0000000..fc66d39
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/proxy.rb
@@ -0,0 +1,116 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # @private
+      # The `AnyInstance::Recorder` is responsible for redefining the klass's
+      # instance method in order to add any stubs/expectations the first time
+      # the method is called. It's not capable of updating a stub on an instance
+      # that's already been previously stubbed (either directly, or via
+      # `any_instance`).
+      #
+      # This proxy sits in front of the recorder and delegates both to it
+      # and to the `RSpec::Mocks::Proxy` for each already mocked or stubbed
+      # instance of the class, in order to propogates changes to the instances.
+      #
+      # Note that unlike `RSpec::Mocks::Proxy`, this proxy class is stateless
+      # and is not persisted in `RSpec::Mocks.space`.
+      #
+      # Proxying for the message expectation fluent interface (typically chained
+      # off of the return value of one of these methods) is provided by the
+      # `FluentInterfaceProxy` class below.
+      class Proxy
+        def initialize(recorder, target_proxies)
+          @recorder       = recorder
+          @target_proxies = target_proxies
+        end
+
+        def klass
+          @recorder.klass
+        end
+
+        def stub(method_name_or_method_map, &block)
+          if Hash === method_name_or_method_map
+            method_name_or_method_map.each do |method_name, return_value|
+              stub(method_name).and_return(return_value)
+            end
+          else
+            perform_proxying(__method__, [method_name_or_method_map], block) do |proxy|
+              proxy.add_stub(method_name_or_method_map, &block)
+            end
+          end
+        end
+
+        def unstub(method_name)
+          perform_proxying(__method__, [method_name], nil) do |proxy|
+            proxy.remove_stub_if_present(method_name)
+          end
+        end
+
+        def stub_chain(*chain, &block)
+          perform_proxying(__method__, chain, block) do |proxy|
+            Mocks::StubChain.stub_chain_on(proxy.object, *chain, &block)
+          end
+        end
+
+        def expect_chain(*chain, &block)
+          perform_proxying(__method__, chain, block) do |proxy|
+            Mocks::ExpectChain.expect_chain_on(proxy.object, *chain, &block)
+          end
+        end
+
+        def should_receive(method_name, &block)
+          perform_proxying(__method__, [method_name], block) do |proxy|
+            # Yeah, this is a bit odd...but if we used `add_message_expectation`
+            # then it would act like `expect_every_instance_of(klass).to receive`.
+            # The any_instance recorder takes care of validating that an instance
+            # received the message.
+            proxy.add_stub(method_name, &block)
+          end
+        end
+
+        def should_not_receive(method_name, &block)
+          perform_proxying(__method__, [method_name], block) do |proxy|
+            proxy.add_message_expectation(method_name, &block).never
+          end
+        end
+
+      private
+
+        def perform_proxying(method_name, args, block, &target_proxy_block)
+          recorder_value = @recorder.__send__(method_name, *args, &block)
+          proxy_values   = @target_proxies.map(&target_proxy_block)
+          FluentInterfaceProxy.new([recorder_value] + proxy_values)
+        end
+      end
+
+      # @private
+      # Delegates messages to each of the given targets in order to
+      # provide the fluent interface that is available off of message
+      # expectations when dealing with `any_instance`.
+      #
+      # `targets` will typically contain 1 of the `AnyInstance::Recorder`
+      # return values and N `MessageExpectation` instances (one per instance
+      # of the `any_instance` klass).
+      class FluentInterfaceProxy
+        def initialize(targets)
+          @targets = targets
+        end
+
+        if RUBY_VERSION.to_f > 1.8
+          def respond_to_missing?(method_name, include_private=false)
+            super || @targets.first.respond_to?(method_name, include_private)
+          end
+        else
+          def respond_to?(method_name, include_private=false)
+            super || @targets.first.respond_to?(method_name, include_private)
+          end
+        end
+
+        def method_missing(*args, &block)
+          return_values = @targets.map { |t| t.__send__(*args, &block) }
+          FluentInterfaceProxy.new(return_values)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/recorder.rb b/rspec-mocks/lib/rspec/mocks/any_instance/recorder.rb
new file mode 100644
index 0000000..271348b
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/recorder.rb
@@ -0,0 +1,267 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # Given a class `TheClass`, `TheClass.any_instance` returns a `Recorder`,
+      # which records stubs and message expectations for later playback on
+      # instances of `TheClass`.
+      #
+      # Further constraints are stored in instances of [Chain](Chain).
+      #
+      # @see AnyInstance
+      # @see Chain
+      class Recorder
+        # @private
+        attr_reader :message_chains, :stubs, :klass
+
+        def initialize(klass)
+          @message_chains = MessageChains.new
+          @stubs = Hash.new { |hash, key| hash[key] = [] }
+          @observed_methods = []
+          @played_methods = {}
+          @klass = klass
+          @expectation_set = false
+        end
+
+        # Initializes the recording a stub to be played back against any
+        # instance of this object that invokes the submitted method.
+        #
+        # @see Methods#stub
+        def stub(method_name, &block)
+          observe!(method_name)
+          message_chains.add(method_name, StubChain.new(self, method_name, &block))
+        end
+
+        # Initializes the recording a stub chain to be played back against any
+        # instance of this object that invokes the method matching the first
+        # argument.
+        #
+        # @see Methods#stub_chain
+        def stub_chain(*method_names_and_optional_return_values, &block)
+          normalize_chain(*method_names_and_optional_return_values) do |method_name, args|
+            observe!(method_name)
+            message_chains.add(method_name, StubChainChain.new(self, *args, &block))
+          end
+        end
+
+        # @private
+        def expect_chain(*method_names_and_optional_return_values, &block)
+          @expectation_set = true
+          normalize_chain(*method_names_and_optional_return_values) do |method_name, args|
+            observe!(method_name)
+            message_chains.add(method_name, ExpectChainChain.new(self, *args, &block))
+          end
+        end
+
+        # Initializes the recording a message expectation to be played back
+        # against any instance of this object that invokes the submitted
+        # method.
+        #
+        # @see Methods#should_receive
+        def should_receive(method_name, &block)
+          @expectation_set = true
+          observe!(method_name)
+          message_chains.add(method_name, PositiveExpectationChain.new(self, method_name, &block))
+        end
+
+        # The opposite of `should_receive`
+        #
+        # @see Methods#should_not_receive
+        def should_not_receive(method_name, &block)
+          should_receive(method_name, &block).never
+        end
+
+        # Removes any previously recorded stubs, stub_chains or message
+        # expectations that use `method_name`.
+        #
+        # @see Methods#unstub
+        def unstub(method_name)
+          unless @observed_methods.include?(method_name.to_sym)
+            raise RSpec::Mocks::MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed"
+          end
+          message_chains.remove_stub_chains_for!(method_name)
+          stubs[method_name].clear
+          stop_observing!(method_name) unless message_chains.has_expectation?(method_name)
+        end
+
+        # @api private
+        #
+        # Used internally to verify that message expectations have been
+        # fulfilled.
+        def verify
+          return unless @expectation_set
+          return if message_chains.all_expectations_fulfilled?
+
+          raise RSpec::Mocks::MockExpectationError,
+                "Exactly one instance should have received the following " \
+                "message(s) but didn't: #{message_chains.unfulfilled_expectations.sort.join(', ')}"
+        end
+
+        # @private
+        def stop_all_observation!
+          @observed_methods.each { |method_name| restore_method!(method_name) }
+        end
+
+        # @private
+        def playback!(instance, method_name)
+          RSpec::Mocks.space.ensure_registered(instance)
+          message_chains.playback!(instance, method_name)
+          @played_methods[method_name] = instance
+          received_expected_message!(method_name) if message_chains.has_expectation?(method_name)
+        end
+
+        # @private
+        def instance_that_received(method_name)
+          @played_methods[method_name]
+        end
+
+        # @private
+        def build_alias_method_name(method_name)
+          "__#{method_name}_without_any_instance__"
+        end
+
+        # @private
+        def already_observing?(method_name)
+          @observed_methods.include?(method_name) || super_class_observing?(method_name)
+        end
+
+        # @private
+        def notify_received_message(_object, message, args, _blk)
+          has_expectation = false
+
+          message_chains.each_unfulfilled_expectation_matching(message, *args) do |expectation|
+            has_expectation = true
+            expectation.expectation_fulfilled!
+          end
+
+          return unless has_expectation
+
+          restore_method!(message)
+          mark_invoked!(message)
+        end
+
+      protected
+
+        def stop_observing!(method_name)
+          restore_method!(method_name)
+          @observed_methods.delete(method_name)
+          super_class_observers_for(method_name).each do |ancestor|
+            ::RSpec::Mocks.space.
+              any_instance_recorder_for(ancestor).stop_observing!(method_name)
+          end
+        end
+
+      private
+
+        def ancestor_is_an_observer?(method_name)
+          lambda do |ancestor|
+            unless ancestor == @klass
+              ::RSpec::Mocks.space.
+                any_instance_recorder_for(ancestor).already_observing?(method_name)
+            end
+          end
+        end
+
+        def super_class_observers_for(method_name)
+          @klass.ancestors.select(&ancestor_is_an_observer?(method_name))
+        end
+
+        def super_class_observing?(method_name)
+          @klass.ancestors.any?(&ancestor_is_an_observer?(method_name))
+        end
+
+        def normalize_chain(*args)
+          args.shift.to_s.split('.').map { |s| s.to_sym }.reverse.each { |a| args.unshift a }
+          yield args.first, args
+        end
+
+        def received_expected_message!(method_name)
+          message_chains.received_expected_message!(method_name)
+          restore_method!(method_name)
+          mark_invoked!(method_name)
+        end
+
+        def restore_method!(method_name)
+          if public_protected_or_private_method_defined?(build_alias_method_name(method_name))
+            restore_original_method!(method_name)
+          else
+            remove_dummy_method!(method_name)
+          end
+        end
+
+        def restore_original_method!(method_name)
+          return unless @klass.instance_method(method_name).owner == @klass
+
+          alias_method_name = build_alias_method_name(method_name)
+          @klass.class_exec do
+            remove_method method_name
+            alias_method method_name, alias_method_name
+            remove_method alias_method_name
+          end
+        end
+
+        def remove_dummy_method!(method_name)
+          @klass.class_exec do
+            remove_method method_name
+          end
+        end
+
+        def backup_method!(method_name)
+          alias_method_name = build_alias_method_name(method_name)
+          @klass.class_exec do
+            alias_method alias_method_name, method_name
+          end if public_protected_or_private_method_defined?(method_name)
+        end
+
+        def public_protected_or_private_method_defined?(method_name)
+          MethodReference.method_defined_at_any_visibility?(@klass, method_name)
+        end
+
+        def observe!(method_name)
+          allow_no_prepended_module_definition_of(method_name)
+
+          if RSpec::Mocks.configuration.verify_partial_doubles?
+            unless public_protected_or_private_method_defined?(method_name)
+              raise MockExpectationError,
+                    "#{@klass} does not implement ##{method_name}"
+            end
+          end
+
+          stop_observing!(method_name) if already_observing?(method_name)
+          @observed_methods << method_name
+          backup_method!(method_name)
+          recorder = self
+          @klass.__send__(:define_method, method_name) do |*args, &blk|
+            recorder.playback!(self, method_name)
+            __send__(method_name, *args, &blk)
+          end
+        end
+
+        def mark_invoked!(method_name)
+          backup_method!(method_name)
+          recorder = self
+          @klass.__send__(:define_method, method_name) do |*_args, &_blk|
+            invoked_instance = recorder.instance_that_received(method_name)
+            inspect = "#<#{self.class}:#{object_id} #{instance_variables.map { |name| "#{name}=#{instance_variable_get name}" }.join(', ')}>"
+            raise RSpec::Mocks::MockExpectationError, "The message '#{method_name}' was received by #{inspect} but has already been received by #{invoked_instance}"
+          end
+        end
+
+        if Support::RubyFeatures.module_prepends_supported?
+          def allow_no_prepended_module_definition_of(method_name)
+            prepended_modules = RSpec::Mocks::Proxy.prepended_modules_of(@klass)
+            problem_mod = prepended_modules.find { |mod| mod.method_defined?(method_name) }
+            return unless problem_mod
+
+            raise RSpec::Mocks::MockExpectationError,
+                  "Using `any_instance` to stub a method (#{method_name}) that has been " \
+                  "defined on a prepended module (#{problem_mod}) is not supported."
+          end
+        else
+          def allow_no_prepended_module_definition_of(_method_name)
+            # nothing to do; prepends aren't supported on this version of ruby
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/stub_chain.rb b/rspec-mocks/lib/rspec/mocks/any_instance/stub_chain.rb
new file mode 100644
index 0000000..adc4e6b
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/stub_chain.rb
@@ -0,0 +1,46 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # @private
+      class StubChain < Chain
+        # @private
+        def expectation_fulfilled?
+          true
+        end
+
+      private
+
+        def create_message_expectation_on(instance)
+          proxy = ::RSpec::Mocks.space.proxy_for(instance)
+          method_name, opts = @expectation_args
+          opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE)
+
+          stub = proxy.add_stub(method_name, opts, &@expectation_block)
+          @recorder.stubs[stub.message] << stub
+
+          if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks?
+            stub.and_yield_receiver_to_implementation
+          end
+
+          stub
+        end
+
+        def invocation_order
+          @invocation_order ||= {
+            :with => [nil],
+            :and_return => [:with, nil],
+            :and_raise => [:with, nil],
+            :and_yield => [:with, nil],
+            :and_call_original => [:with, nil],
+            :and_wrap_original => [:with, nil]
+          }
+        end
+
+        def verify_invocation_order(rspec_method_name, *_args, &_block)
+          return if invocation_order[rspec_method_name].include?(last_message)
+          raise NoMethodError, "Undefined method #{rspec_method_name}"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/any_instance/stub_chain_chain.rb b/rspec-mocks/lib/rspec/mocks/any_instance/stub_chain_chain.rb
new file mode 100644
index 0000000..c056967
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/any_instance/stub_chain_chain.rb
@@ -0,0 +1,27 @@
+module RSpec
+  module Mocks
+    module AnyInstance
+      # @private
+      class StubChainChain < StubChain
+        def initialize(*args)
+          super
+          @expectation_fulfilled = false
+        end
+
+      private
+
+        def create_message_expectation_on(instance)
+          ::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block)
+        end
+
+        def invocation_order
+          @invocation_order ||= {
+            :and_return => [nil],
+            :and_raise => [nil],
+            :and_yield => [nil]
+          }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/argument_list_matcher.rb b/rspec-mocks/lib/rspec/mocks/argument_list_matcher.rb
new file mode 100644
index 0000000..453bf9f
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/argument_list_matcher.rb
@@ -0,0 +1,100 @@
+# We intentionally do not use the `RSpec::Support.require...` methods
+# here so that this file can be loaded individually, as documented
+# below.
+require 'rspec/mocks/argument_matchers'
+require 'rspec/support/fuzzy_matcher'
+
+module RSpec
+  module Mocks
+    # Wrapper for matching arguments against a list of expected values. Used by
+    # the `with` method on a `MessageExpectation`:
+    #
+    #     expect(object).to receive(:message).with(:a, 'b', 3)
+    #     object.message(:a, 'b', 3)
+    #
+    # Values passed to `with` can be literal values or argument matchers that
+    # match against the real objects .e.g.
+    #
+    #     expect(object).to receive(:message).with(hash_including(:a => 'b'))
+    #
+    # Can also be used directly to match the contents of any `Array`. This
+    # enables 3rd party mocking libs to take advantage of rspec's argument
+    # matching without using the rest of rspec-mocks.
+    #
+    #     require 'rspec/mocks/argument_list_matcher'
+    #     include RSpec::Mocks::ArgumentMatchers
+    #
+    #     arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b'))
+    #     arg_list_matcher.args_match?(123, :a => 'b')
+    #
+    # This class is immutable.
+    #
+    # @see ArgumentMatchers
+    class ArgumentListMatcher
+      # @private
+      attr_reader :expected_args
+
+      # @api public
+      # @param [Array] expected_args a list of expected literals and/or argument matchers
+      #
+      # Initializes an `ArgumentListMatcher` with a collection of literal
+      # values and/or argument matchers.
+      #
+      # @see ArgumentMatchers
+      # @see #args_match?
+      def initialize(*expected_args)
+        @expected_args = expected_args
+        ensure_expected_args_valid!
+      end
+
+      # @api public
+      # @param [Array] args
+      #
+      # Matches each element in the `expected_args` against the element in the same
+      # position of the arguments passed to `new`.
+      #
+      # @see #initialize
+      def args_match?(*args)
+        Support::FuzzyMatcher.values_match?(resolve_expected_args_based_on(args), args)
+      end
+
+      # @private
+      # Resolves abstract arg placeholders like `no_args` and `any_args` into
+      # a more concrete arg list based on the provided `actual_args`.
+      def resolve_expected_args_based_on(actual_args)
+        return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args
+
+        any_args_index = expected_args.index(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
+        return expected_args unless any_args_index
+
+        replace_any_args_with_splat_of_anything(any_args_index, actual_args.count)
+      end
+
+    private
+
+      def replace_any_args_with_splat_of_anything(before_count, actual_args_count)
+        any_args_count  = actual_args_count   - expected_args.count + 1
+        after_count     = expected_args.count - before_count        - 1
+
+        any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE }
+        expected_args.first(before_count) + any_args + expected_args.last(after_count)
+      end
+
+      def ensure_expected_args_valid!
+        if expected_args.count(ArgumentMatchers::AnyArgsMatcher::INSTANCE) > 1
+          raise ArgumentError, "`any_args` can only be passed to " \
+                "`with` once but you have passed it multiple times."
+        elsif expected_args.count > 1 && expected_args.include?(ArgumentMatchers::NoArgsMatcher::INSTANCE)
+          raise ArgumentError, "`no_args` can only be passed as a " \
+                "singleton argument to `with` (i.e. `with(no_args)`), " \
+                "but you have passed additional arguments."
+        end
+      end
+
+      # Value that will match all argument lists.
+      #
+      # @private
+      MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/argument_matchers.rb b/rspec-mocks/lib/rspec/mocks/argument_matchers.rb
new file mode 100644
index 0000000..8fcfd02
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/argument_matchers.rb
@@ -0,0 +1,320 @@
+# This cannot take advantage of our relative requires, since this file is a
+# dependency of `rspec/mocks/argument_list_matcher.rb`. See comment there for
+# details.
+require 'rspec/support/matcher_definition'
+
+module RSpec
+  module Mocks
+    # ArgumentMatchers are placeholders that you can include in message
+    # expectations to match arguments against a broader check than simple
+    # equality.
+    #
+    # With the exception of `any_args` and `no_args`, they all match against
+    # the arg in same position in the argument list.
+    #
+    # @see ArgumentListMatcher
+    module ArgumentMatchers
+      # Acts like an arg splat, matching any number of args at any point in an arg list.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(1, 2, any_args)
+      #
+      #   # matches any of these:
+      #   object.message(1, 2)
+      #   object.message(1, 2, 3)
+      #   object.message(1, 2, 3, 4)
+      def any_args
+        AnyArgsMatcher::INSTANCE
+      end
+
+      # Matches any argument at all.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(anything)
+      def anything
+        AnyArgMatcher::INSTANCE
+      end
+
+      # Matches no arguments.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(no_args)
+      def no_args
+        NoArgsMatcher::INSTANCE
+      end
+
+      # Matches if the actual argument responds to the specified messages.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(duck_type(:hello))
+      #   expect(object).to receive(:message).with(duck_type(:hello, :goodbye))
+      def duck_type(*args)
+        DuckTypeMatcher.new(*args)
+      end
+
+      # Matches a boolean value.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(boolean())
+      def boolean
+        BooleanMatcher::INSTANCE
+      end
+
+      # Matches a hash that includes the specified key(s) or key/value pairs.
+      # Ignores any additional keys.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(hash_including(:key => val))
+      #   expect(object).to receive(:message).with(hash_including(:key))
+      #   expect(object).to receive(:message).with(hash_including(:key, :key2 => val2))
+      def hash_including(*args)
+        HashIncludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args))
+      end
+
+      # Matches an array that includes the specified items at least once.
+      # Ignores duplicates and additional values
+      #
+      # @example
+      #   expect(object).to receive(:message).with(array_including(1,2,3))
+      #   expect(object).to receive(:message).with(array_including([1,2,3]))
+      def array_including(*args)
+        actually_an_array = Array === args.first && args.count == 1 ? args.first : args
+        ArrayIncludingMatcher.new(actually_an_array)
+      end
+
+      # Matches a hash that doesn't include the specified key(s) or key/value.
+      #
+      # @example
+      #   expect(object).to receive(:message).with(hash_excluding(:key => val))
+      #   expect(object).to receive(:message).with(hash_excluding(:key))
+      #   expect(object).to receive(:message).with(hash_excluding(:key, :key2 => :val2))
+      def hash_excluding(*args)
+        HashExcludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args))
+      end
+
+      alias_method :hash_not_including, :hash_excluding
+
+      # Matches if `arg.instance_of?(klass)`
+      #
+      # @example
+      #   expect(object).to receive(:message).with(instance_of(Thing))
+      def instance_of(klass)
+        InstanceOf.new(klass)
+      end
+
+      alias_method :an_instance_of, :instance_of
+
+      # Matches if `arg.kind_of?(klass)`
+      #
+      # @example
+      #   expect(object).to receive(:message).with(kind_of(Thing))
+      def kind_of(klass)
+        KindOf.new(klass)
+      end
+
+      alias_method :a_kind_of, :kind_of
+
+      # @private
+      def self.anythingize_lonely_keys(*args)
+        hash = args.last.class == Hash ? args.delete_at(-1) : {}
+        args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE }
+        hash
+      end
+
+      # Intended to be subclassed by stateless, immutable argument matchers.
+      # Provides a `<klass name>::INSTANCE` constant for accessing a global
+      # singleton instance of the matcher. There is no need to construct
+      # multiple instance since there is no state. It also facilities the
+      # special case logic we need for some of these matchers, by making it
+      # easy to do comparisons like: `[klass::INSTANCE] == args` rather than
+      # `args.count == 1 && klass === args.first`.
+      #
+      # @private
+      class SingletonMatcher
+        private_class_method :new
+
+        def self.inherited(subklass)
+          subklass.const_set(:INSTANCE, subklass.send(:new))
+        end
+      end
+
+      # @private
+      class AnyArgsMatcher < SingletonMatcher
+        def description
+          "*(any args)"
+        end
+      end
+
+      # @private
+      class AnyArgMatcher < SingletonMatcher
+        def ===(_other)
+          true
+        end
+
+        def description
+          "anything"
+        end
+      end
+
+      # @private
+      class NoArgsMatcher < SingletonMatcher
+        def description
+          "no args"
+        end
+      end
+
+      # @private
+      class BooleanMatcher < SingletonMatcher
+        def ===(value)
+          true == value || false == value
+        end
+
+        def description
+          "boolean"
+        end
+      end
+
+      # @private
+      class BaseHashMatcher
+        def initialize(expected)
+          @expected = expected
+        end
+
+        def ===(predicate, actual)
+          @expected.__send__(predicate) do |k, v|
+            actual.key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k])
+          end
+        rescue NoMethodError
+          false
+        end
+
+        def description(name)
+          "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})"
+        end
+
+      private
+
+        def formatted_expected_hash
+          Hash[
+            @expected.map do |k, v|
+              k = RSpec::Support.rspec_description_for_object(k)
+              v = RSpec::Support.rspec_description_for_object(v)
+
+              [k, v]
+            end
+          ]
+        end
+      end
+
+      # @private
+      class HashIncludingMatcher < BaseHashMatcher
+        def ===(actual)
+          super(:all?, actual)
+        end
+
+        def description
+          super("hash_including")
+        end
+      end
+
+      # @private
+      class HashExcludingMatcher < BaseHashMatcher
+        def ===(actual)
+          super(:none?, actual)
+        end
+
+        def description
+          super("hash_not_including")
+        end
+      end
+
+      # @private
+      class ArrayIncludingMatcher
+        def initialize(expected)
+          @expected = expected
+        end
+
+        def ===(actual)
+          actual = actual.uniq
+          @expected.uniq.all? do |expected_element|
+            actual.any? do |actual_element|
+              RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element)
+            end
+          end
+        end
+
+        def description
+          "array_including(#{formatted_expected_values})"
+        end
+
+      private
+
+        def formatted_expected_values
+          @expected.map do |x|
+            RSpec::Support.rspec_description_for_object(x)
+          end.join(", ")
+        end
+      end
+
+      # @private
+      class DuckTypeMatcher
+        def initialize(*methods_to_respond_to)
+          @methods_to_respond_to = methods_to_respond_to
+        end
+
+        def ===(value)
+          @methods_to_respond_to.all? { |message| value.respond_to?(message) }
+        end
+
+        def description
+          "duck_type(#{@methods_to_respond_to.map(&:inspect).join(', ')})"
+        end
+      end
+
+      # @private
+      class InstanceOf
+        def initialize(klass)
+          @klass = klass
+        end
+
+        def ===(actual)
+          actual.instance_of?(@klass)
+        end
+
+        def description
+          "an_instance_of(#{@klass.name})"
+        end
+      end
+
+      # @private
+      class KindOf
+        def initialize(klass)
+          @klass = klass
+        end
+
+        def ===(actual)
+          actual.kind_of?(@klass)
+        end
+
+        def description
+          "kind of #{@klass.name}"
+        end
+      end
+
+      matcher_namespace = name + '::'
+      ::RSpec::Support.register_matcher_definition do |object|
+        # This is the best we have for now. We should tag all of our matchers
+        # with a module or something so we can test for it directly.
+        #
+        # (Note Module#parent in ActiveSupport is defined in a similar way.)
+        begin
+          object.class.name.include?(matcher_namespace)
+        rescue NoMethodError
+          # Some objects, like BasicObject, don't implemented standard
+          # reflection methods.
+          false
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/configuration.rb b/rspec-mocks/lib/rspec/mocks/configuration.rb
new file mode 100644
index 0000000..28b22b8
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/configuration.rb
@@ -0,0 +1,187 @@
+module RSpec
+  module Mocks
+    # Provides configuration options for rspec-mocks.
+    class Configuration
+      def initialize
+        @yield_receiver_to_any_instance_implementation_blocks = true
+        @verify_doubled_constant_names = false
+        @transfer_nested_constants = false
+        @verify_partial_doubles = false
+      end
+
+      def yield_receiver_to_any_instance_implementation_blocks?
+        @yield_receiver_to_any_instance_implementation_blocks
+      end
+
+      # Sets whether or not RSpec will yield the receiving instance of a
+      # message to blocks that are used for any_instance stub implementations.
+      # When set, the first yielded argument will be the receiving instance.
+      # Defaults to `true`.
+      #
+      # @example
+      #   RSpec.configure do |rspec|
+      #     rspec.mock_with :rspec do |mocks|
+      #       mocks.yield_receiver_to_any_instance_implementation_blocks = false
+      #     end
+      #   end
+      attr_writer :yield_receiver_to_any_instance_implementation_blocks
+
+      # Adds `stub` and `should_receive` to the given
+      # modules or classes. This is usually only necessary
+      # if you application uses some proxy classes that
+      # "strip themselves down" to a bare minimum set of
+      # methods and remove `stub` and `should_receive` in
+      # the process.
+      #
+      # @example
+      #   RSpec.configure do |rspec|
+      #     rspec.mock_with :rspec do |mocks|
+      #       mocks.add_stub_and_should_receive_to Delegator
+      #     end
+      #   end
+      #
+      def add_stub_and_should_receive_to(*modules)
+        modules.each do |mod|
+          Syntax.enable_should(mod)
+        end
+      end
+
+      # Provides the ability to set either `expect`,
+      # `should` or both syntaxes. RSpec uses `expect`
+      # syntax by default. This is needed if you want to
+      # explicitly enable `should` syntax and/or explicitly
+      # disable `expect` syntax.
+      #
+      # @example
+      #   RSpec.configure do |rspec|
+      #     rspec.mock_with :rspec do |mocks|
+      #       mocks.syntax = [:expect, :should]
+      #     end
+      #  end
+      #
+      def syntax=(*values)
+        syntaxes = values.flatten
+        if syntaxes.include?(:expect)
+          Syntax.enable_expect
+        else
+          Syntax.disable_expect
+        end
+
+        if syntaxes.include?(:should)
+          Syntax.enable_should
+        else
+          Syntax.disable_should
+        end
+      end
+
+      # Returns an array with a list of syntaxes
+      # that are enabled.
+      #
+      # @example
+      #   unless RSpec::Mocks.configuration.syntax.include?(:expect)
+      #     raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax"
+      #   end
+      #
+      def syntax
+        syntaxes = []
+        syntaxes << :should  if Syntax.should_enabled?
+        syntaxes << :expect if Syntax.expect_enabled?
+        syntaxes
+      end
+
+      def verify_doubled_constant_names?
+        !!@verify_doubled_constant_names
+      end
+
+      # When this is set to true, an error will be raised when
+      # `instance_double` or `class_double` is given the name of an undefined
+      # constant. You probably only want to set this when running your entire
+      # test suite, with all production code loaded. Setting this for an
+      # isolated unit test will prevent you from being able to isolate it!
+      attr_writer :verify_doubled_constant_names
+
+      # Provides a way to perform customisations when verifying doubles.
+      #
+      # @example
+      #  RSpec::Mocks.configuration.when_declaring_verifying_double do |ref|
+      #    ref.some_method!
+      #  end
+      def when_declaring_verifying_double(&block)
+        verifying_double_declaration_callbacks << block
+      end
+
+      # @api private
+      # Returns an array of blocks to call when verifying doubles
+      def verifying_double_declaration_callbacks
+        @verifying_double_declaration_callbacks ||= []
+      end
+
+      def transfer_nested_constants?
+        !!@transfer_nested_constants
+      end
+
+      # Sets the default for the `transfer_nested_constants` option when
+      # stubbing constants.
+      attr_writer :transfer_nested_constants
+
+      # When set to true, partial mocks will be verified the same as object
+      # doubles. Any stubs will have their arguments checked against the original
+      # method, and methods that do not exist cannot be stubbed.
+      def verify_partial_doubles=(val)
+        @verify_partial_doubles = !!val
+      end
+
+      def verify_partial_doubles?
+        @verify_partial_doubles
+      end
+
+      if ::RSpec.respond_to?(:configuration)
+        def color?
+          ::RSpec.configuration.color_enabled?
+        end
+      else
+        # Indicates whether or not diffs should be colored.
+        # Delegates to rspec-core's color option if rspec-core
+        # is loaded; otherwise you can set it here.
+        attr_writer :color
+
+        # Indicates whether or not diffs should be colored.
+        # Delegates to rspec-core's color option if rspec-core
+        # is loaded; otherwise you can set it here.
+        def color?
+          @color
+        end
+      end
+
+      # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed
+      # objects. By default this will not work since RSpec mocks works by
+      # adding singleton methods that cannot be serialized. This patch removes
+      # these singleton methods before serialization. Setting to falsey removes
+      # the patch.
+      #
+      # This method is idempotent.
+      def patch_marshal_to_support_partial_doubles=(val)
+        if val
+          RSpec::Mocks::MarshalExtension.patch!
+        else
+          RSpec::Mocks::MarshalExtension.unpatch!
+        end
+      end
+
+      # @api private
+      # Resets the configured syntax to the default.
+      def reset_syntaxes_to_default
+        self.syntax = [:should, :expect]
+        RSpec::Mocks::Syntax.warn_about_should!
+      end
+    end
+
+    # Mocks specific configuration, as distinct from `RSpec.configuration`
+    # which is core RSpec configuration.
+    def self.configuration
+      @configuration ||= Configuration.new
+    end
+
+    configuration.reset_syntaxes_to_default
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/error_generator.rb b/rspec-mocks/lib/rspec/mocks/error_generator.rb
new file mode 100644
index 0000000..9603567
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/error_generator.rb
@@ -0,0 +1,310 @@
+RSpec::Support.require_rspec_support 'differ'
+
+module RSpec
+  module Mocks
+    # Raised when a message expectation is not satisfied.
+    MockExpectationError = Class.new(Exception)
+
+    # Raised when a test double is used after it has been torn
+    # down (typically at the end of an rspec-core example).
+    ExpiredTestDoubleError = Class.new(MockExpectationError)
+
+    # Raised when doubles or partial doubles are used outside of the per-test lifecycle.
+    OutsideOfExampleError = Class.new(StandardError)
+
+    # Raised when an expectation customization method (e.g. `with`,
+    # `and_return`) is called on a message expectation which has already been
+    # invoked.
+    MockExpectationAlreadyInvokedError = Class.new(Exception)
+
+    # Raised for situations that RSpec cannot support due to mutations made
+    # externally on arguments that RSpec is holding onto to use for later
+    # comparisons.
+    #
+    # @deprecated We no longer raise this error but the constant remains until
+    #   RSpec 4 for SemVer reasons.
+    CannotSupportArgMutationsError = Class.new(StandardError)
+
+    # @private
+    UnsupportedMatcherError  = Class.new(StandardError)
+    # @private
+    NegationUnsupportedError = Class.new(StandardError)
+    # @private
+    VerifyingDoubleNotDefinedError = Class.new(StandardError)
+
+    # @private
+    class ErrorGenerator
+      attr_writer :opts
+
+      def initialize(target, name)
+        @target = target
+        @name = name
+      end
+
+      # @private
+      def opts
+        @opts ||= {}
+      end
+
+      # @private
+      def raise_unexpected_message_error(message, *args)
+        __raise "#{intro} received unexpected message :#{message}#{arg_message(*args)}"
+      end
+
+      # @private
+      def raise_unexpected_message_args_error(expectation, *args)
+        expected_args = format_args(*expectation.expected_args)
+        actual_args = format_received_args(*args)
+        diff = diff_message(expectation.expected_args, args)
+
+        message = default_error_message(expectation, expected_args, actual_args)
+        message << "\nDiff:#{diff}" unless diff.empty?
+
+        __raise message
+      end
+
+      # @private
+      def raise_missing_default_stub_error(expectation, *args)
+        expected_args = format_args(*expectation.expected_args)
+        actual_args = format_received_args(*args)
+        diff = diff_message(expectation.expected_args, args)
+
+        message = default_error_message(expectation, expected_args, actual_args)
+        message << "\nDiff:\n #{diff}" unless diff.empty?
+        message << "\n Please stub a default value first if message might be received with other args as well. \n"
+
+        __raise message
+      end
+
+      # @private
+      def raise_similar_message_args_error(expectation, *args_for_multiple_calls)
+        expected_args = format_args(*expectation.expected_args)
+        actual_args = args_for_multiple_calls.map { |a| format_received_args(*a) }.join(", ")
+
+        __raise(default_error_message(expectation, expected_args, actual_args))
+      end
+
+      def default_error_message(expectation, expected_args, actual_args)
+        [
+          intro,
+          "received",
+          expectation.message.inspect,
+          unexpected_arguments_message(expected_args, actual_args),
+        ].join(" ")
+      end
+
+      # rubocop:disable Style/ParameterLists
+      # @private
+      def raise_expectation_error(message, expected_received_count, argument_list_matcher, actual_received_count, expectation_count_type, *args)
+        expected_part = expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher)
+        received_part = received_part_of_expectation_error(actual_received_count, *args)
+        __raise "(#{intro}).#{message}#{format_args(*args)}\n    #{expected_part}\n    #{received_part}"
+      end
+      # rubocop:enable Style/ParameterLists
+
+      # @private
+      def raise_unimplemented_error(doubled_module, method_name)
+        __raise "%s does not implement: %s" % [
+          doubled_module.description,
+          method_name
+        ]
+      end
+
+      # @private
+      def raise_non_public_error(method_name, visibility)
+        raise NoMethodError, "%s method `%s' called on %s" % [
+          visibility, method_name, intro
+        ]
+      end
+
+      # @private
+      def raise_invalid_arguments_error(verifier)
+        __raise verifier.error_message
+      end
+
+      # @private
+      def raise_expired_test_double_error
+        raise ExpiredTestDoubleError,
+              "#{intro} was originally created in one example but has leaked into " \
+              "another example and can no longer be used. rspec-mocks' doubles are " \
+              "designed to only last for one example, and you need to create a new " \
+              "one in each example you wish to use it for."
+      end
+
+      # @private
+      def received_part_of_expectation_error(actual_received_count, *args)
+        "received: #{count_message(actual_received_count)}" +
+          actual_method_call_args_description(actual_received_count, args)
+      end
+
+      # @private
+      def expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher)
+        "expected: #{count_message(expected_received_count, expectation_count_type)}" +
+          expected_method_call_args_description(argument_list_matcher.expected_args)
+      end
+
+      # @private
+      def actual_method_call_args_description(count, args)
+        method_call_args_description(args) ||
+          if count > 0 && args.length > 0
+            " with arguments: #{args.inspect.gsub(/\A\[(.+)\]\z/, '(\1)')}"
+          else
+            ""
+          end
+      end
+
+      # @private
+      def expected_method_call_args_description(args)
+        method_call_args_description(args) ||
+          if args.length > 0
+            " with arguments: #{format_args(*args)}"
+          else
+            ""
+          end
+      end
+
+      # @private
+      def method_call_args_description(args)
+        case args.first
+        when ArgumentMatchers::AnyArgsMatcher then " with any arguments"
+        when ArgumentMatchers::NoArgsMatcher  then " with no arguments"
+        end
+      end
+
+      # @private
+      def describe_expectation(verb, message, expected_received_count, _actual_received_count, *args)
+        "#{verb} #{message}#{format_args(*args)} #{count_message(expected_received_count)}"
+      end
+
+      # @private
+      def raise_out_of_order_error(message)
+        __raise "#{intro} received :#{message} out of order"
+      end
+
+      # @private
+      def raise_block_failed_error(message, detail)
+        __raise "#{intro} received :#{message} but passed block failed with: #{detail}"
+      end
+
+      # @private
+      def raise_missing_block_error(args_to_yield)
+        __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
+      end
+
+      # @private
+      def raise_wrong_arity_error(args_to_yield, signature)
+        __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with #{signature.description}"
+      end
+
+      # @private
+      def raise_only_valid_on_a_partial_double(method)
+        __raise "#{intro} is a pure test double. `#{method}` is only " \
+                "available on a partial double."
+      end
+
+      # @private
+      def raise_expectation_on_unstubbed_method(method)
+        __raise "#{intro} expected to have received #{method}, but that " \
+                "object is not a spy or method has not been stubbed."
+      end
+
+      # @private
+      def raise_expectation_on_mocked_method(method)
+        __raise "#{intro} expected to have received #{method}, but that " \
+                "method has been mocked instead of stubbed or spied."
+      end
+
+      def self.raise_double_negation_error(wrapped_expression)
+        raise "Isn't life confusing enough? You've already set a " \
+              "negative message expectation and now you are trying to " \
+              "negate it again with `never`. What does an expression like " \
+              "`#{wrapped_expression}.not_to receive(:msg).never` even mean?"
+      end
+
+    private
+
+      def unexpected_arguments_message(expected_args_string, actual_args_string)
+        "with unexpected arguments\n  expected: #{expected_args_string}\n       got: #{actual_args_string}"
+      end
+
+      def diff_message(expected_args, actual_args)
+        formatted_expected_args = expected_args.map do |x|
+          RSpec::Support.rspec_description_for_object(x)
+        end
+
+        formatted_expected_args, actual_args = unpack_string_args(formatted_expected_args, actual_args)
+
+        differ.diff(actual_args, formatted_expected_args)
+      end
+
+      def unpack_string_args(formatted_expected_args, actual_args)
+        if [formatted_expected_args, actual_args].all? { |x| list_of_exactly_one_string?(x) }
+          [formatted_expected_args.first, actual_args.first]
+        else
+          [formatted_expected_args, actual_args]
+        end
+      end
+
+      def list_of_exactly_one_string?(args)
+        Array === args && args.count == 1 && String === args.first
+      end
+
+      def differ
+        RSpec::Support::Differ.new(:color => RSpec::Mocks.configuration.color?)
+      end
+
+      def intro
+        if @name
+          "Double #{@name.inspect}"
+        elsif TestDouble === @target
+          "Double"
+        elsif Class === @target
+          "<#{@target.inspect} (class)>"
+        elsif @target
+          @target
+        else
+          "nil"
+        end
+      end
+
+      def __raise(message)
+        message = opts[:message] unless opts[:message].nil?
+        Kernel.raise(RSpec::Mocks::MockExpectationError, message)
+      end
+
+      def arg_message(*args)
+        " with " + format_args(*args)
+      end
+
+      def format_args(*args)
+        args.empty? ? "(no args)" : "(" + arg_list(*args) + ")"
+      end
+
+      def arg_list(*args)
+        args.map { |arg| arg_has_valid_description?(arg) ? arg.description : arg.inspect }.join(", ")
+      end
+
+      def arg_has_valid_description?(arg)
+        RSpec::Support.is_a_matcher?(arg) && arg.respond_to?(:description)
+      end
+
+      def format_received_args(*args)
+        args.empty? ? "(no args)" : "(" + received_arg_list(*args) + ")"
+      end
+
+      def received_arg_list(*args)
+        args.map(&:inspect).join(", ")
+      end
+
+      def count_message(count, expectation_count_type=nil)
+        return "at least #{times(count.abs)}" if count < 0 || expectation_count_type == :at_least
+        return "at most #{times(count)}" if expectation_count_type == :at_most
+        times(count)
+      end
+
+      def times(count)
+        "#{count} time#{count == 1 ? '' : 's'}"
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/example_methods.rb b/rspec-mocks/lib/rspec/mocks/example_methods.rb
new file mode 100644
index 0000000..04c4ca9
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/example_methods.rb
@@ -0,0 +1,424 @@
+RSpec::Support.require_rspec_mocks 'object_reference'
+
+module RSpec
+  module Mocks
+    # Contains methods intended to be used from within code examples.
+    # Mix this in to your test context (such as a test framework base class)
+    # to use rspec-mocks with your test framework. If you're using rspec-core,
+    # it'll take care of doing this for you.
+    module ExampleMethods
+      include RSpec::Mocks::ArgumentMatchers
+
+      # @overload double()
+      # @overload double(name)
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload double(stubs)
+      #   @param stubs (Hash) hash of message/return-value pairs
+      # @overload double(name, stubs)
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs (Hash) hash of message/return-value pairs
+      # @return (Double)
+      #
+      # Constructs an instance of [RSpec::Mocks::Double](RSpec::Mocks::Double) configured
+      # with an optional name, used for reporting in failure messages, and an optional
+      # hash of message/return-value pairs.
+      #
+      # @example
+      #   book = double("book", :title => "The RSpec Book")
+      #   book.title #=> "The RSpec Book"
+      #
+      #   card = double("card", :suit => "Spades", :rank => "A")
+      #   card.suit  #=> "Spades"
+      #   card.rank  #=> "A"
+      #
+      def double(*args)
+        ExampleMethods.declare_double(Double, *args)
+      end
+
+      # @overload instance_double(doubled_class)
+      #   @param doubled_class [String, Class]
+      # @overload instance_double(doubled_class, name)
+      #   @param doubled_class [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload instance_double(doubled_class, stubs)
+      #   @param doubled_class [String, Class]
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @overload instance_double(doubled_class, name, stubs)
+      #   @param doubled_class [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @return InstanceVerifyingDouble
+      #
+      # Constructs a test double against a specific class. If the given class
+      # name has been loaded, only instance methods defined on the class are
+      # allowed to be stubbed. In all other ways it behaves like a
+      # [double](double).
+      def instance_double(doubled_class, *args)
+        ref = ObjectReference.for(doubled_class)
+        ExampleMethods.declare_verifying_double(InstanceVerifyingDouble, ref, *args)
+      end
+
+      # @overload class_double(doubled_class)
+      #   @param doubled_class [String, Module]
+      # @overload class_double(doubled_class, name)
+      #   @param doubled_class [String, Module]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload class_double(doubled_class, stubs)
+      #   @param doubled_class [String, Module]
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @overload class_double(doubled_class, name, stubs)
+      #   @param doubled_class [String, Module]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @return ClassVerifyingDouble
+      #
+      # Constructs a test double against a specific class. If the given class
+      # name has been loaded, only class methods defined on the class are
+      # allowed to be stubbed. In all other ways it behaves like a
+      # [double](double).
+      def class_double(doubled_class, *args)
+        ref = ObjectReference.for(doubled_class)
+        ExampleMethods.declare_verifying_double(ClassVerifyingDouble, ref, *args)
+      end
+
+      # @overload object_double(object_or_name)
+      #   @param object_or_name [String, Object]
+      # @overload object_double(object_or_name, name)
+      #   @param object_or_name [String, Object]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload object_double(object_or_name, stubs)
+      #   @param object_or_name [String, Object]
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @overload object_double(object_or_name, name, stubs)
+      #   @param object_or_name [String, Object]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @return ObjectVerifyingDouble
+      #
+      # Constructs a test double against a specific object. Only the methods
+      # the object responds to are allowed to be stubbed. If a String argument
+      # is provided, it is assumed to reference a constant object which is used
+      # for verification. In all other ways it behaves like a [double](double).
+      def object_double(object_or_name, *args)
+        ref = ObjectReference.for(object_or_name, :allow_direct_object_refs)
+        ExampleMethods.declare_verifying_double(ObjectVerifyingDouble, ref, *args)
+      end
+
+      # @overload spy()
+      # @overload spy(name)
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload spy(stubs)
+      #   @param stubs (Hash) hash of message/return-value pairs
+      # @overload spy(name, stubs)
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs (Hash) hash of message/return-value pairs
+      # @return (Double)
+      #
+      # Constructs a test double that is optimized for use with
+      # `have_received`. With a normal double one has to stub methods in order
+      # to be able to spy them. A spy automatically spies on all methods.
+      def spy(*args)
+        double(*args).as_null_object
+      end
+
+      # @overload instance_spy(doubled_class)
+      #   @param doubled_class [String, Class]
+      # @overload instance_spy(doubled_class, name)
+      #   @param doubled_class [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload instance_spy(doubled_class, stubs)
+      #   @param doubled_class [String, Class]
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @overload instance_spy(doubled_class, name, stubs)
+      #   @param doubled_class [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @return InstanceVerifyingDouble
+      #
+      # Constructs a test double that is optimized for use with `have_received`
+      # against a specific class. If the given class name has been loaded, only
+      # instance methods defined on the class are allowed to be stubbed.  With
+      # a normal double one has to stub methods in order to be able to spy
+      # them. An instance_spy automatically spies on all instance methods to
+      # which the class responds.
+      def instance_spy(*args)
+        instance_double(*args).as_null_object
+      end
+
+      # @overload object_spy(object_or_name)
+      #   @param object_or_name [String, Object]
+      # @overload object_spy(object_or_name, name)
+      #   @param object_or_name [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload object_spy(object_or_name, stubs)
+      #   @param object_or_name [String, Object]
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @overload object_spy(object_or_name, name, stubs)
+      #   @param object_or_name [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @return ObjectVerifyingDouble
+      #
+      # Constructs a test double that is optimized for use with `have_received`
+      # against a specific object. Only instance methods defined on the object
+      # are allowed to be stubbed.  With a normal double one has to stub
+      # methods in order to be able to spy them. An object_spy automatically
+      # spies on all methods to which the object responds.
+      def object_spy(*args)
+        object_double(*args).as_null_object
+      end
+
+      # @overload class_spy(doubled_class)
+      #   @param doubled_class [String, Module]
+      # @overload class_spy(doubled_class, name)
+      #   @param doubled_class [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      # @overload class_spy(doubled_class, stubs)
+      #   @param doubled_class [String, Module]
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @overload class_spy(doubled_class, name, stubs)
+      #   @param doubled_class [String, Class]
+      #   @param name [String/Symbol] name or description to be used in failure messages
+      #   @param stubs [Hash] hash of message/return-value pairs
+      # @return ClassVerifyingDouble
+      #
+      # Constructs a test double that is optimized for use with `have_received`
+      # against a specific class. If the given class name has been loaded,
+      # only class methods defined on the class are allowed to be stubbed.
+      # With a normal double one has to stub methods in order to be able to spy
+      # them. An class_spy automatically spies on all class methods to which the
+      # class responds.
+      def class_spy(*args)
+        class_double(*args).as_null_object
+      end
+
+      # Disables warning messages about expectations being set on nil.
+      #
+      # By default warning messages are issued when expectations are set on
+      # nil.  This is to prevent false-positives and to catch potential bugs
+      # early on.
+      def allow_message_expectations_on_nil
+        RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false
+      end
+
+      # Stubs the named constant with the given value.
+      # Like method stubs, the constant will be restored
+      # to its original value (or lack of one, if it was
+      # undefined) when the example completes.
+      #
+      # @param constant_name [String] The fully qualified name of the constant. The current
+      #   constant scoping at the point of call is not considered.
+      # @param value [Object] The value to make the constant refer to. When the
+      #   example completes, the constant will be restored to its prior state.
+      # @param options [Hash] Stubbing options.
+      # @option options :transfer_nested_constants [Boolean, Array<Symbol>] Determines
+      #   what nested constants, if any, will be transferred from the original value
+      #   of the constant to the new value of the constant. This only works if both
+      #   the original and new values are modules (or classes).
+      # @return [Object] the stubbed value of the constant
+      #
+      # @example
+      #   stub_const("MyClass", Class.new) # => Replaces (or defines) MyClass with a new class object.
+      #   stub_const("SomeModel::PER_PAGE", 5) # => Sets SomeModel::PER_PAGE to 5.
+      #
+      #   class CardDeck
+      #     SUITS = [:Spades, :Diamonds, :Clubs, :Hearts]
+      #     NUM_CARDS = 52
+      #   end
+      #
+      #   stub_const("CardDeck", Class.new)
+      #   CardDeck::SUITS # => uninitialized constant error
+      #   CardDeck::NUM_CARDS # => uninitialized constant error
+      #
+      #   stub_const("CardDeck", Class.new, :transfer_nested_constants => true)
+      #   CardDeck::SUITS # => our suits array
+      #   CardDeck::NUM_CARDS # => 52
+      #
+      #   stub_const("CardDeck", Class.new, :transfer_nested_constants => [:SUITS])
+      #   CardDeck::SUITS # => our suits array
+      #   CardDeck::NUM_CARDS # => uninitialized constant error
+      def stub_const(constant_name, value, options={})
+        ConstantMutator.stub(constant_name, value, options)
+      end
+
+      # Hides the named constant with the given value. The constant will be
+      # undefined for the duration of the test.
+      #
+      # Like method stubs, the constant will be restored to its original value
+      # when the example completes.
+      #
+      # @param constant_name [String] The fully qualified name of the constant.
+      #   The current constant scoping at the point of call is not considered.
+      #
+      # @example
+      #   hide_const("MyClass") # => MyClass is now an undefined constant
+      def hide_const(constant_name)
+        ConstantMutator.hide(constant_name)
+      end
+
+      # Verifies that the given object received the expected message during the
+      # course of the test. On a spy objects or as null object doubles this
+      # works for any method, on other objects the method must have
+      # been stubbed beforehand in order for messages to be verified.
+      #
+      # Stubbing and verifying messages received in this way implements the
+      # Test Spy pattern.
+      #
+      # @param method_name [Symbol] name of the method expected to have been
+      #   called.
+      #
+      # @example
+      #   invitation = double('invitation', accept: true)
+      #   user.accept_invitation(invitation)
+      #   expect(invitation).to have_received(:accept)
+      #
+      #   # You can also use most message expectations:
+      #   expect(invitation).to have_received(:accept).with(mailer).once
+      #
+      # @note `have_received(...).with(...)` is unable to work properly when
+      #   passed arguments are mutated after the spy records the received message.
+      def have_received(method_name, &block)
+        Matchers::HaveReceived.new(method_name, &block)
+      end
+
+      # @method expect
+      # Used to wrap an object in preparation for setting a mock expectation
+      # on it.
+      #
+      # @example
+      #   expect(obj).to receive(:foo).with(5).and_return(:return_value)
+      #
+      # @note This method is usually provided by rspec-expectations. However,
+      #   if you use rspec-mocks without rspec-expectations, there's a definition
+      #   of it that is made available here. If you disable the `:expect` syntax
+      #   this method will be undefined.
+
+      # @method allow
+      # Used to wrap an object in preparation for stubbing a method
+      # on it.
+      #
+      # @example
+      #   allow(dbl).to receive(:foo).with(5).and_return(:return_value)
+      #
+      # @note If you disable the `:expect` syntax this method will be undefined.
+
+      # @method expect_any_instance_of
+      # Used to wrap a class in preparation for setting a mock expectation
+      # on instances of it.
+      #
+      # @example
+      #   expect_any_instance_of(MyClass).to receive(:foo)
+      #
+      # @note If you disable the `:expect` syntax this method will be undefined.
+
+      # @method allow_any_instance_of
+      # Used to wrap a class in preparation for stubbing a method
+      # on instances of it.
+      #
+      # @example
+      #   allow_any_instance_of(MyClass).to receive(:foo)
+      #
+      # @note This is only available when you have enabled the `expect` syntax.
+
+      # @method receive
+      # Used to specify a message that you expect or allow an object
+      # to receive. The object returned by `receive` supports the same
+      # fluent interface that `should_receive` and `stub` have always
+      # supported, allowing you to constrain the arguments or number of
+      # times, and configure how the object should respond to the message.
+      #
+      # @example
+      #   expect(obj).to receive(:hello).with("world").exactly(3).times
+      #
+      # @note If you disable the `:expect` syntax this method will be undefined.
+
+      # @method receive_messages
+      # Shorthand syntax used to setup message(s), and their return value(s),
+      # that you expect or allow an object to receive. The method takes a hash
+      # of messages and their respective return values. Unlike with `receive`,
+      # you cannot apply further customizations using a block or the fluent
+      # interface.
+      #
+      # @example
+      #   allow(obj).to receive_messages(:speak => "Hello World")
+      #   allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow")
+      #
+      # @note If you disable the `:expect` syntax this method will be undefined.
+
+      # @method receive_message_chain
+      # @overload receive_message_chain(method1, method2)
+      # @overload receive_message_chain("method1.method2")
+      # @overload receive_message_chain(method1, method_to_value_hash)
+      #
+      # stubs/mocks a chain of messages on an object or test double.
+      #
+      # ## Warning:
+      #
+      # Chains can be arbitrarily long, which makes it quite painless to
+      # violate the Law of Demeter in violent ways, so you should consider any
+      # use of `receive_message_chain` a code smell. Even though not all code smells
+      # indicate real problems (think fluent interfaces), `receive_message_chain` still
+      # results in brittle examples.  For example, if you write
+      # `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the
+      # implementation calls `foo.baz.bar`, the stub will not work.
+      #
+      # @example
+      #   allow(double).to receive_message_chain("foo.bar") { :baz }
+      #   allow(double).to receive_message_chain(:foo, :bar => :baz)
+      #   allow(double).to receive_message_chain(:foo, :bar) { :baz }
+      #
+      #   # Given any of ^^ these three forms ^^:
+      #   double.foo.bar # => :baz
+      #
+      #   # Common use in Rails/ActiveRecord:
+      #   allow(Article).to receive_message_chain("recent.published") { [Article.new] }
+      #
+      # @note If you disable the `:expect` syntax this method will be undefined.
+
+      # @private
+      def self.included(klass)
+        klass.class_exec do
+          # This gets mixed in so that if `RSpec::Matchers` is included in
+          # `klass` later, it's definition of `expect` will take precedence.
+          include ExpectHost unless method_defined?(:expect)
+        end
+      end
+
+      # @private
+      def self.extended(object)
+        # This gets extended in so that if `RSpec::Matchers` is included in
+        # `klass` later, it's definition of `expect` will take precedence.
+        object.extend ExpectHost unless object.respond_to?(:expect)
+      end
+
+      # @private
+      def self.declare_verifying_double(type, ref, *args)
+        if RSpec::Mocks.configuration.verify_doubled_constant_names? &&
+          !ref.defined?
+
+          raise VerifyingDoubleNotDefinedError,
+                "#{ref.description.inspect} is not a defined constant. " \
+                "Perhaps you misspelt it? " \
+                "Disable check with `verify_doubled_constant_names` configuration option."
+        end
+
+        RSpec::Mocks.configuration.verifying_double_declaration_callbacks.each do |block|
+          block.call(ref)
+        end
+
+        declare_double(type, ref, *args)
+      end
+
+      # @private
+      def self.declare_double(type, *args)
+        args << {} unless Hash === args.last
+        type.new(*args)
+      end
+
+      # This module exists to host the `expect` method for cases where
+      # rspec-mocks is used w/o rspec-expectations.
+      module ExpectHost
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/instance_method_stasher.rb b/rspec-mocks/lib/rspec/mocks/instance_method_stasher.rb
new file mode 100644
index 0000000..44145ca
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/instance_method_stasher.rb
@@ -0,0 +1,135 @@
+module RSpec
+  module Mocks
+    # @private
+    class InstanceMethodStasher
+      def initialize(object, method)
+        @object = object
+        @method = method
+        @klass = (class << object; self; end)
+
+        @original_method = nil
+        @method_is_stashed = false
+      end
+
+      attr_reader :original_method
+
+      if RUBY_VERSION.to_f < 1.9
+        # @private
+        def method_is_stashed?
+          @method_is_stashed
+        end
+
+        # @private
+        def stash
+          return if !method_defined_directly_on_klass? || @method_is_stashed
+
+          @klass.__send__(:alias_method, stashed_method_name, @method)
+          @method_is_stashed = true
+        end
+
+        # @private
+        def stashed_method_name
+          "obfuscated_by_rspec_mocks__#{@method}"
+        end
+        private :stashed_method_name
+
+        # @private
+        def restore
+          return unless @method_is_stashed
+
+          if @klass.__send__(:method_defined?, @method)
+            @klass.__send__(:undef_method, @method)
+          end
+          @klass.__send__(:alias_method, @method, stashed_method_name)
+          @klass.__send__(:remove_method, stashed_method_name)
+          @method_is_stashed = false
+        end
+      else
+
+        # @private
+        def method_is_stashed?
+          !!@original_method
+        end
+
+        # @private
+        def stash
+          return unless method_defined_directly_on_klass?
+          @original_method ||= ::RSpec::Support.method_handle_for(@object, @method)
+        end
+
+        # @private
+        def restore
+          return unless @original_method
+
+          if @klass.__send__(:method_defined?, @method)
+            @klass.__send__(:undef_method, @method)
+          end
+
+          handle_restoration_failures do
+            @klass.__send__(:define_method, @method, @original_method)
+          end
+
+          @original_method = nil
+        end
+      end
+
+      if RUBY_DESCRIPTION.include?('2.0.0p247') || RUBY_DESCRIPTION.include?('2.0.0p195')
+        # ruby 2.0.0-p247 and 2.0.0-p195 both have a bug that we can't work around :(.
+        # https://bugs.ruby-lang.org/issues/8686
+        def handle_restoration_failures
+          yield
+        rescue TypeError
+          RSpec.warn_with(
+            "RSpec failed to properly restore a partial double (#{@object.inspect}) " \
+            "to its original state due to a known bug in MRI 2.0.0-p195 & p247 " \
+            "(https://bugs.ruby-lang.org/issues/8686). This object may remain " \
+            "screwed up for the rest of this process. Please upgrade to 2.0.0-p353 or above.",
+            :call_site => nil, :use_spec_location_as_call_site => true
+          )
+        end
+      else
+        def handle_restoration_failures
+          # No known reasons for restoration to fail on other rubies.
+          yield
+        end
+      end
+
+    private
+
+      # @private
+      def method_defined_directly_on_klass?
+        method_defined_on_klass? && method_owned_by_klass?
+      end
+
+      # @private
+      def method_defined_on_klass?(klass=@klass)
+        MethodReference.method_defined_at_any_visibility?(klass, @method)
+      end
+
+      def method_owned_by_klass?
+        owner = @klass.instance_method(@method).owner
+
+        # On Ruby 2.0.0+ the owner of a method on a class which has been
+        # `prepend`ed may actually be an instance, e.g.
+        # `#<MyClass:0x007fbb94e3cd10>`, rather than the expected `MyClass`.
+        owner = owner.class unless Module === owner
+
+        # On some 1.9s (e.g. rubinius) aliased methods
+        # can report the wrong owner. Example:
+        # class MyClass
+        #   class << self
+        #     alias alternate_new new
+        #   end
+        # end
+        #
+        # MyClass.owner(:alternate_new) returns `Class` when incorrect,
+        # but we need to consider the owner to be `MyClass` because
+        # it is not actually available on `Class` but is on `MyClass`.
+        # Hence, we verify that the owner actually has the method defined.
+        # If the given owner does not have the method defined, we assume
+        # that the method is actually owned by @klass.
+        owner == @klass || !(method_defined_on_klass?(owner))
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/marshal_extension.rb b/rspec-mocks/lib/rspec/mocks/marshal_extension.rb
new file mode 100644
index 0000000..cfa9c1a
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/marshal_extension.rb
@@ -0,0 +1,41 @@
+module RSpec
+  module Mocks
+    # Support for `patch_marshal_to_support_partial_doubles` configuration.
+    #
+    # @private
+    class MarshalExtension
+      def self.patch!
+        return if Marshal.respond_to?(:dump_with_rspec_mocks)
+
+        Marshal.instance_eval do
+          class << self
+            def dump_with_rspec_mocks(object, *rest)
+              if !::RSpec::Mocks.space.registered?(object) || NilClass === object
+                dump_without_rspec_mocks(object, *rest)
+              else
+                dump_without_rspec_mocks(object.dup, *rest)
+              end
+            end
+
+            alias_method :dump_without_rspec_mocks, :dump
+            undef_method :dump
+            alias_method :dump, :dump_with_rspec_mocks
+          end
+        end
+      end
+
+      def self.unpatch!
+        return unless Marshal.respond_to?(:dump_with_rspec_mocks)
+
+        Marshal.instance_eval do
+          class << self
+            undef_method :dump_with_rspec_mocks
+            undef_method :dump
+            alias_method :dump, :dump_without_rspec_mocks
+            undef_method :dump_without_rspec_mocks
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/matchers/expectation_customization.rb b/rspec-mocks/lib/rspec/mocks/matchers/expectation_customization.rb
new file mode 100644
index 0000000..81e6427
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/matchers/expectation_customization.rb
@@ -0,0 +1,20 @@
+module RSpec
+  module Mocks
+    module Matchers
+      # @private
+      class ExpectationCustomization
+        attr_accessor :block
+
+        def initialize(method_name, args, block)
+          @method_name = method_name
+          @args        = args
+          @block       = block
+        end
+
+        def playback_onto(expectation)
+          expectation.__send__(@method_name, *@args, &@block)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/matchers/have_received.rb b/rspec-mocks/lib/rspec/mocks/matchers/have_received.rb
new file mode 100644
index 0000000..b7611c6
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/matchers/have_received.rb
@@ -0,0 +1,119 @@
+module RSpec
+  module Mocks
+    module Matchers
+      # @private
+      class HaveReceived
+        COUNT_CONSTRAINTS = %w[exactly at_least at_most times once twice thrice]
+        ARGS_CONSTRAINTS = %w[with]
+        CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS + %w[ordered]
+
+        def initialize(method_name, &block)
+          @method_name = method_name
+          @block = block
+          @constraints = []
+          @subject = nil
+        end
+
+        def name
+          "have_received"
+        end
+
+        def matches?(subject, &block)
+          @block ||= block
+          @subject = subject
+          @expectation = expect
+          mock_proxy.ensure_implemented(@method_name)
+
+          expected_messages_received_in_order?
+        end
+
+        def does_not_match?(subject)
+          @subject = subject
+          ensure_count_unconstrained
+          @expectation = expect.never
+          mock_proxy.ensure_implemented(@method_name)
+          expected_messages_received_in_order?
+        end
+
+        def failure_message
+          generate_failure_message
+        end
+
+        def failure_message_when_negated
+          generate_failure_message
+        end
+
+        def description
+          (@expectation ||= expect).description_for("have received")
+        end
+
+        CONSTRAINTS.each do |expectation|
+          define_method expectation do |*args|
+            @constraints << [expectation, *args]
+            self
+          end
+        end
+
+        def setup_allowance(_subject, &_block)
+          disallow("allow", " as it would have no effect")
+        end
+
+        def setup_any_instance_allowance(_subject, &_block)
+          disallow("allow_any_instance_of")
+        end
+
+        def setup_any_instance_expectation(_subject, &_block)
+          disallow("expect_any_instance_of")
+        end
+
+      private
+
+        def disallow(type, reason="")
+          raise RSpec::Mocks::MockExpectationError,
+                "Using #{type}(...) with the `have_received` " \
+                "matcher is not supported#{reason}."
+        end
+
+        def expect
+          expectation = mock_proxy.build_expectation(@method_name)
+          apply_constraints_to expectation
+          expectation
+        end
+
+        def apply_constraints_to(expectation)
+          @constraints.each do |constraint|
+            expectation.send(*constraint)
+          end
+        end
+
+        def ensure_count_unconstrained
+          return unless count_constraint
+          raise RSpec::Mocks::MockExpectationError,
+                "can't use #{count_constraint} when negative"
+        end
+
+        def count_constraint
+          @constraints.map(&:first).find do |constraint|
+            COUNT_CONSTRAINTS.include?(constraint)
+          end
+        end
+
+        def generate_failure_message
+          mock_proxy.check_for_unexpected_arguments(@expectation)
+          @expectation.generate_error
+        rescue RSpec::Mocks::MockExpectationError => error
+          error.message
+        end
+
+        def expected_messages_received_in_order?
+          mock_proxy.replay_received_message_on @expectation, &@block
+          @expectation.expected_messages_received? && @expectation.ensure_expected_ordering_received!
+        end
+
+        def mock_proxy
+          RSpec::Mocks.space.proxy_for(@subject)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/matchers/receive.rb b/rspec-mocks/lib/rspec/mocks/matchers/receive.rb
new file mode 100644
index 0000000..a16b28f
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/matchers/receive.rb
@@ -0,0 +1,130 @@
+RSpec::Support.require_rspec_mocks 'matchers/expectation_customization'
+
+module RSpec
+  module Mocks
+    module Matchers
+      # @private
+      class Receive
+        def initialize(message, block)
+          @message                 = message
+          @block                   = block
+          @recorded_customizations = []
+        end
+
+        def name
+          "receive"
+        end
+
+        def description
+          describable.description_for("receive")
+        end
+
+        def setup_expectation(subject, &block)
+          warn_if_any_instance("expect", subject)
+          @describable = setup_mock_proxy_method_substitute(subject, :add_message_expectation, block)
+        end
+        alias matches? setup_expectation
+
+        def setup_negative_expectation(subject, &block)
+          # ensure `never` goes first for cases like `never.and_return(5)`,
+          # where `and_return` is meant to raise an error
+          @recorded_customizations.unshift ExpectationCustomization.new(:never, [], nil)
+
+          warn_if_any_instance("expect", subject)
+
+          setup_expectation(subject, &block)
+        end
+        alias does_not_match? setup_negative_expectation
+
+        def setup_allowance(subject, &block)
+          warn_if_any_instance("allow", subject)
+          setup_mock_proxy_method_substitute(subject, :add_stub, block)
+        end
+
+        def setup_any_instance_expectation(subject, &block)
+          setup_any_instance_method_substitute(subject, :should_receive, block)
+        end
+
+        def setup_any_instance_negative_expectation(subject, &block)
+          setup_any_instance_method_substitute(subject, :should_not_receive, block)
+        end
+
+        def setup_any_instance_allowance(subject, &block)
+          setup_any_instance_method_substitute(subject, :stub, block)
+        end
+
+        MessageExpectation.public_instance_methods(false).each do |method|
+          next if method_defined?(method)
+
+          define_method(method) do |*args, &block|
+            @recorded_customizations << ExpectationCustomization.new(method, args, block)
+            self
+          end
+        end
+
+      private
+
+        def describable
+          @describable ||= DefaultDescribable.new(@message)
+        end
+
+        def warn_if_any_instance(expression, subject)
+          return unless AnyInstance::Proxy === subject
+
+          RSpec.warning(
+            "`#{expression}(#{subject.klass}.any_instance).to` " \
+            "is probably not what you meant, it does not operate on " \
+            "any instance of `#{subject.klass}`. " \
+            "Use `#{expression}_any_instance_of(#{subject.klass}).to` instead."
+          )
+        end
+
+        def setup_mock_proxy_method_substitute(subject, method, block)
+          proxy = ::RSpec::Mocks.space.proxy_for(subject)
+          setup_method_substitute(proxy, method, block)
+        end
+
+        def setup_any_instance_method_substitute(subject, method, block)
+          proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject)
+          setup_method_substitute(proxy, method, block)
+        end
+
+        def setup_method_substitute(host, method, block, *args)
+          args << @message.to_sym
+          block = move_block_to_last_customization(block)
+
+          expectation = host.__send__(method, *args, &(@block || block))
+
+          @recorded_customizations.each do |customization|
+            customization.playback_onto(expectation)
+          end
+          expectation
+        end
+
+        def move_block_to_last_customization(block)
+          last = @recorded_customizations.last
+          return block unless last
+
+          last.block ||= block
+          nil
+        end
+
+        # MessageExpectation objects are able to describe themselves in detail.
+        # We use this as a fall back when a MessageExpectation is not available.
+        # @private
+        class DefaultDescribable
+          def initialize(message)
+            @message = message
+          end
+
+          # This is much simpler for the `any_instance` case than what the
+          # user may want, but I'm not up for putting a bunch of effort
+          # into full descriptions for `any_instance` expectations at this point :(.
+          def description_for(verb)
+            "#{verb} #{@message}"
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/matchers/receive_message_chain.rb b/rspec-mocks/lib/rspec/mocks/matchers/receive_message_chain.rb
new file mode 100644
index 0000000..d831cd3
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/matchers/receive_message_chain.rb
@@ -0,0 +1,80 @@
+RSpec::Support.require_rspec_mocks 'matchers/expectation_customization'
+
+module RSpec
+  module Mocks
+    module Matchers
+      # @private
+      class ReceiveMessageChain
+        def initialize(chain, &block)
+          @chain = chain
+          @block = block
+          @recorded_customizations  = []
+        end
+
+        [:with, :and_return, :and_throw, :and_raise, :and_yield, :and_call_original].each do |msg|
+          define_method(msg) do |*args, &block|
+            @recorded_customizations << ExpectationCustomization.new(msg, args, block)
+            self
+          end
+        end
+
+        def name
+          "receive_message_chain"
+        end
+
+        def description
+          "receive message chain #{formatted_chain}"
+        end
+
+        def setup_allowance(subject, &block)
+          chain = StubChain.stub_chain_on(subject, *@chain, &(@block || block))
+          replay_customizations(chain)
+        end
+
+        def setup_any_instance_allowance(subject, &block)
+          proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject)
+          chain = proxy.stub_chain(*@chain, &(@block || block))
+          replay_customizations(chain)
+        end
+
+        def setup_any_instance_expectation(subject, &block)
+          proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject)
+          chain = proxy.expect_chain(*@chain, &(@block || block))
+          replay_customizations(chain)
+        end
+
+        def setup_expectation(subject, &block)
+          chain = ExpectChain.expect_chain_on(subject, *@chain, &(@block || block))
+          replay_customizations(chain)
+        end
+
+        def setup_negative_expectation(*_args)
+          raise NegationUnsupportedError,
+                "`expect(...).not_to receive_message_chain` is not supported " \
+                "since it doesn't really make sense. What would it even mean?"
+        end
+
+        alias matches? setup_expectation
+        alias does_not_match? setup_negative_expectation
+
+      private
+
+        def replay_customizations(chain)
+          @recorded_customizations.each do |customization|
+            customization.playback_onto(chain)
+          end
+        end
+
+        def formatted_chain
+          @formatted_chain ||= @chain.map do |part|
+            if Hash === part
+              part.keys.first.to_s
+            else
+              part.to_s
+            end
+          end.join(".")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/matchers/receive_messages.rb b/rspec-mocks/lib/rspec/mocks/matchers/receive_messages.rb
new file mode 100644
index 0000000..b6316aa
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/matchers/receive_messages.rb
@@ -0,0 +1,75 @@
+module RSpec
+  module Mocks
+    module Matchers
+      # @private
+      class ReceiveMessages
+        def initialize(message_return_value_hash)
+          @message_return_value_hash = message_return_value_hash
+          @backtrace_line = CallerFilter.first_non_rspec_line
+        end
+
+        def name
+          "receive_messages"
+        end
+
+        def description
+          "receive messages: #{@message_return_value_hash.inspect}"
+        end
+
+        def setup_expectation(subject)
+          warn_about_block if block_given?
+          each_message_on(proxy_on(subject)) do |host, message, return_value|
+            host.add_simple_expectation(message, return_value, @backtrace_line)
+          end
+        end
+        alias matches? setup_expectation
+
+        def setup_negative_expectation(_subject)
+          raise NegationUnsupportedError,
+                "`expect(...).to_not receive_messages` is not supported since it " \
+                "doesn't really make sense. What would it even mean?"
+        end
+        alias does_not_match? setup_negative_expectation
+
+        def setup_allowance(subject)
+          warn_about_block if block_given?
+          each_message_on(proxy_on(subject)) do |host, message, return_value|
+            host.add_simple_stub(message, return_value)
+          end
+        end
+
+        def setup_any_instance_expectation(subject)
+          warn_about_block if block_given?
+          each_message_on(any_instance_of(subject)) do |host, message, return_value|
+            host.should_receive(message).and_return(return_value)
+          end
+        end
+
+        def setup_any_instance_allowance(subject)
+          warn_about_block if block_given?
+          any_instance_of(subject).stub(@message_return_value_hash)
+        end
+
+        def warn_about_block
+          raise "Implementation blocks aren't supported with `receive_messages`"
+        end
+
+      private
+
+        def proxy_on(subject)
+          ::RSpec::Mocks.space.proxy_for(subject)
+        end
+
+        def any_instance_of(subject)
+          ::RSpec::Mocks.space.any_instance_proxy_for(subject)
+        end
+
+        def each_message_on(host)
+          @message_return_value_hash.each do |message, value|
+            yield host, message, value
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/message_chain.rb b/rspec-mocks/lib/rspec/mocks/message_chain.rb
new file mode 100644
index 0000000..4106cb2
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/message_chain.rb
@@ -0,0 +1,91 @@
+module RSpec
+  module Mocks
+    # @private
+    class MessageChain
+      attr_reader :object, :chain, :block
+
+      def initialize(object, *chain, &blk)
+        @object = object
+        @chain, @block = format_chain(*chain, &blk)
+      end
+
+      # @api private
+      def setup_chain
+        if chain.length > 1
+          if (matching_stub = find_matching_stub)
+            chain.shift
+            chain_on(matching_stub.invoke(nil), *chain, &@block)
+          elsif (matching_expectation = find_matching_expectation)
+            chain.shift
+            chain_on(matching_expectation.invoke_without_incrementing_received_count(nil), *chain, &@block)
+          else
+            next_in_chain = Double.new
+            expectation(object, chain.shift) { next_in_chain }
+            chain_on(next_in_chain, *chain, &@block)
+          end
+        else
+          expectation(object, chain.shift, &@block)
+        end
+      end
+
+    private
+
+      def expectation(_object, _message, &_return_block)
+        raise NotImplementedError
+      end
+
+      def chain_on(object, *chain, &block)
+        initialize(object, *chain, &block)
+        setup_chain
+      end
+
+      def format_chain(*chain, &blk)
+        if Hash === chain.last
+          hash = chain.pop
+          hash.each do |k, v|
+            chain << k
+            blk = Proc.new { v }
+          end
+        end
+        return chain.join('.').split('.'), blk
+      end
+
+      def find_matching_stub
+        ::RSpec::Mocks.space.proxy_for(object).
+          __send__(:find_matching_method_stub, chain.first.to_sym)
+      end
+
+      def find_matching_expectation
+        ::RSpec::Mocks.space.proxy_for(object).
+          __send__(:find_matching_expectation, chain.first.to_sym)
+      end
+    end
+
+    # @private
+    class ExpectChain < MessageChain
+      # @api private
+      def self.expect_chain_on(object, *chain, &blk)
+        new(object, *chain, &blk).setup_chain
+      end
+
+    private
+
+      def expectation(object, message, &return_block)
+        ::RSpec::Mocks.expect_message(object, message, {}, &return_block)
+      end
+    end
+
+    # @private
+    class StubChain < MessageChain
+      def self.stub_chain_on(object, *chain, &blk)
+        new(object, *chain, &blk).setup_chain
+      end
+
+    private
+
+      def expectation(object, message, &return_block)
+        ::RSpec::Mocks.allow_message(object, message, {}, &return_block)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/message_expectation.rb b/rspec-mocks/lib/rspec/mocks/message_expectation.rb
new file mode 100644
index 0000000..43d8479
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/message_expectation.rb
@@ -0,0 +1,714 @@
+module RSpec
+  module Mocks
+    # A message expectation that only allows concrete return values to be set
+    # for a message. While this same effect can be achieved using a standard
+    # MessageExpecation, this version is much faster and so can be used as an
+    # optimization.
+    #
+    # @private
+    class SimpleMessageExpectation
+      def initialize(message, response, error_generator, backtrace_line=nil)
+        @message, @response, @error_generator, @backtrace_line = message.to_sym, response, error_generator, backtrace_line
+        @received = false
+      end
+
+      def invoke(*_)
+        @received = true
+        @response
+      end
+
+      def matches?(message, *_)
+        @message == message.to_sym
+      end
+
+      def called_max_times?
+        false
+      end
+
+      def verify_messages_received
+        InsertOntoBacktrace.line(@backtrace_line) do
+          unless @received
+            @error_generator.raise_expectation_error(@message, 1, ArgumentListMatcher::MATCH_ALL, 0, nil)
+          end
+        end
+      end
+    end
+
+    # Represents an individual method stub or message expectation. The methods
+    # defined here can be used to configure how it behaves. The methods return
+    # `self` so that they can be chained together to form a fluent interface.
+    class MessageExpectation
+      # @!group Configuring Responses
+
+      # @overload and_return(value)
+      # @overload and_return(first_value, second_value)
+      #
+      # Tells the object to return a value when it receives the message.  Given
+      # more than one value, the first value is returned the first time the
+      # message is received, the second value is returned the next time, etc,
+      # etc.
+      #
+      # If the message is received more times than there are values, the last
+      # value is received for every subsequent call.
+      #
+      # @return [nil] No further chaining is supported after this.
+      # @example
+      #   allow(counter).to receive(:count).and_return(1)
+      #   counter.count # => 1
+      #   counter.count # => 1
+      #
+      #   allow(counter).to receive(:count).and_return(1,2,3)
+      #   counter.count # => 1
+      #   counter.count # => 2
+      #   counter.count # => 3
+      #   counter.count # => 3
+      #   counter.count # => 3
+      #   # etc
+      def and_return(first_value, *values)
+        raise_already_invoked_error_if_necessary(__method__)
+        if negative?
+          raise "`and_return` is not supported with negative message expectations"
+        end
+
+        if block_given?
+          raise ArgumentError, "Implementation blocks aren't supported with `and_return`"
+        end
+
+        values.unshift(first_value)
+        @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least)
+        self.terminal_implementation_action = AndReturnImplementation.new(values)
+
+        nil
+      end
+
+      # Tells the object to delegate to the original unmodified method
+      # when it receives the message.
+      #
+      # @note This is only available on partial doubles.
+      #
+      # @return [nil] No further chaining is supported after this.
+      # @example
+      #   expect(counter).to receive(:increment).and_call_original
+      #   original_count = counter.count
+      #   counter.increment
+      #   expect(counter.count).to eq(original_count + 1)
+      def and_call_original
+        and_wrap_original do |original, *args, &block|
+          original.call(*args, &block)
+        end
+      end
+
+      # Decorates the stubbed method with the supplied block. The original
+      # unmodified method is passed to the block along with any method call
+      # arguments so you can delegate to it, whilst still being able to
+      # change what args are passed to it and/or change the return value.
+      #
+      # @note This is only available on partial doubles.
+      #
+      # @return [nil] No further chaining is supported after this.
+      # @example
+      #   expect(api).to receive(:large_list).and_wrap_original do |original_method, *args, &block|
+      #     original_method.call(*args, &block).first(10)
+      #   end
+      def and_wrap_original(&block)
+        if RSpec::Mocks::TestDouble === @method_double.object
+          @error_generator.raise_only_valid_on_a_partial_double(:and_call_original)
+        else
+          warn_about_stub_override if implementation.inner_action
+          @implementation = AndWrapOriginalImplementation.new(@method_double.original_method, block)
+          @yield_receiver_to_implementation_block = false
+        end
+
+        nil
+      end
+
+      # @overload and_raise
+      # @overload and_raise(ExceptionClass)
+      # @overload and_raise(ExceptionClass, message)
+      # @overload and_raise(exception_instance)
+      #
+      # Tells the object to raise an exception when the message is received.
+      #
+      # @return [nil] No further chaining is supported after this.
+      # @note
+      #   When you pass an exception class, the MessageExpectation will raise
+      #   an instance of it, creating it with `exception` and passing `message`
+      #   if specified.  If the exception class initializer requires more than
+      #   one parameters, you must pass in an instance and not the class,
+      #   otherwise this method will raise an ArgumentError exception.
+      #
+      # @example
+      #   allow(car).to receive(:go).and_raise
+      #   allow(car).to receive(:go).and_raise(OutOfGas)
+      #   allow(car).to receive(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive")
+      #   allow(car).to receive(:go).and_raise(OutOfGas.new(2, :oz))
+      def and_raise(exception=RuntimeError, message=nil)
+        raise_already_invoked_error_if_necessary(__method__)
+        if exception.respond_to?(:exception)
+          exception = message ? exception.exception(message) : exception.exception
+        end
+
+        self.terminal_implementation_action = Proc.new { raise exception }
+        nil
+      end
+
+      # @overload and_throw(symbol)
+      # @overload and_throw(symbol, object)
+      #
+      # Tells the object to throw a symbol (with the object if that form is
+      # used) when the message is received.
+      #
+      # @return [nil] No further chaining is supported after this.
+      # @example
+      #   allow(car).to receive(:go).and_throw(:out_of_gas)
+      #   allow(car).to receive(:go).and_throw(:out_of_gas, :level => 0.1)
+      def and_throw(*args)
+        raise_already_invoked_error_if_necessary(__method__)
+        self.terminal_implementation_action = Proc.new { throw(*args) }
+        nil
+      end
+
+      # Tells the object to yield one or more args to a block when the message
+      # is received.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   stream.stub(:open).and_yield(StringIO.new)
+      def and_yield(*args, &block)
+        raise_already_invoked_error_if_necessary(__method__)
+        yield @eval_context = Object.new if block
+        @args_to_yield << args
+        self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator)
+        self
+      end
+      # @!endgroup
+
+      # @!group Constraining Receive Counts
+
+      # Constrain a message expectation to be received a specific number of
+      # times.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(dealer).to receive(:deal_card).exactly(10).times
+      def exactly(n, &block)
+        raise_already_invoked_error_if_necessary(__method__)
+        self.inner_implementation_action = block
+        set_expected_received_count :exactly, n
+        self
+      end
+
+      # Constrain a message expectation to be received at least a specific
+      # number of times.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(dealer).to receive(:deal_card).at_least(9).times
+      def at_least(n, &block)
+        raise_already_invoked_error_if_necessary(__method__)
+        set_expected_received_count :at_least, n
+
+        if n == 0
+          raise "at_least(0) has been removed, use allow(...).to receive(:message) instead"
+        end
+
+        self.inner_implementation_action = block
+
+        self
+      end
+
+      # Constrain a message expectation to be received at most a specific
+      # number of times.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(dealer).to receive(:deal_card).at_most(10).times
+      def at_most(n, &block)
+        raise_already_invoked_error_if_necessary(__method__)
+        self.inner_implementation_action = block
+        set_expected_received_count :at_most, n
+        self
+      end
+
+      # Syntactic sugar for `exactly`, `at_least` and `at_most`
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(dealer).to receive(:deal_card).exactly(10).times
+      #   expect(dealer).to receive(:deal_card).at_least(10).times
+      #   expect(dealer).to receive(:deal_card).at_most(10).times
+      def times(&block)
+        self.inner_implementation_action = block
+        self
+      end
+
+      # Expect a message not to be received at all.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(car).to receive(:stop).never
+      def never
+        ErrorGenerator.raise_double_negation_error("expect(obj)") if negative?
+        @expected_received_count = 0
+        self
+      end
+
+      # Expect a message to be received exactly one time.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(car).to receive(:go).once
+      def once(&block)
+        self.inner_implementation_action = block
+        set_expected_received_count :exactly, 1
+        self
+      end
+
+      # Expect a message to be received exactly two times.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(car).to receive(:go).twice
+      def twice(&block)
+        self.inner_implementation_action = block
+        set_expected_received_count :exactly, 2
+        self
+      end
+
+      # Expect a message to be received exactly three times.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(car).to receive(:go).thrice
+      def thrice(&block)
+        self.inner_implementation_action = block
+        set_expected_received_count :exactly, 3
+        self
+      end
+      # @!endgroup
+
+      # @!group Other Constraints
+
+      # Constrains a stub or message expectation to invocations with specific
+      # arguments.
+      #
+      # With a stub, if the message might be received with other args as well,
+      # you should stub a default value first, and then stub or mock the same
+      # message using `with` to constrain to specific arguments.
+      #
+      # A message expectation will fail if the message is received with different
+      # arguments.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   allow(cart).to receive(:add) { :failure }
+      #   allow(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success }
+      #   cart.add(Book.new(:isbn => 1234567890))
+      #   # => :failure
+      #   cart.add(Book.new(:isbn => 1934356379))
+      #   # => :success
+      #
+      #   expect(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success }
+      #   cart.add(Book.new(:isbn => 1234567890))
+      #   # => failed expectation
+      #   cart.add(Book.new(:isbn => 1934356379))
+      #   # => passes
+      def with(*args, &block)
+        raise_already_invoked_error_if_necessary(__method__)
+        if args.empty?
+          raise ArgumentError,
+                "`with` must have at least one argument. Use `no_args` matcher to set the expectation of receiving no arguments."
+        end
+
+        self.inner_implementation_action = block
+        @argument_list_matcher = ArgumentListMatcher.new(*args)
+        self
+      end
+
+      # Expect messages to be received in a specific order.
+      #
+      # @return [MessageExpecation] self, to support further chaining.
+      # @example
+      #   expect(api).to receive(:prepare).ordered
+      #   expect(api).to receive(:run).ordered
+      #   expect(api).to receive(:finish).ordered
+      def ordered(&block)
+        self.inner_implementation_action = block
+        additional_expected_calls.times do
+          @order_group.register(self)
+        end
+        @ordered = true
+        self
+      end
+
+      # @private
+      # Contains the parts of `MessageExpecation` that aren't part of
+      # rspec-mocks' public API. The class is very big and could really use
+      # some collaborators it delegates to for this stuff but for now this was
+      # the simplest way to split the public from private stuff to make it
+      # easier to publish the docs for the APIs we want published.
+      module ImplementationDetails
+        attr_accessor :error_generator, :implementation
+        attr_reader :message
+        attr_reader :orig_object
+        attr_writer :expected_received_count, :expected_from, :argument_list_matcher
+        protected :expected_received_count=, :expected_from=, :error_generator, :error_generator=, :implementation=
+
+        # rubocop:disable Style/ParameterLists
+        def initialize(error_generator, expectation_ordering, expected_from, method_double,
+                       type=:expectation, opts={}, &implementation_block)
+          @error_generator = error_generator
+          @error_generator.opts = opts
+          @expected_from = expected_from
+          @method_double = method_double
+          @orig_object = @method_double.object
+          @message = @method_double.method_name
+          @actual_received_count = 0
+          @expected_received_count = type == :expectation ? 1 : :any
+          @argument_list_matcher = ArgumentListMatcher::MATCH_ALL
+          @order_group = expectation_ordering
+          @order_group.register(self) unless type == :stub
+          @expectation_type = type
+          @ordered = false
+          @at_least = @at_most = @exactly = nil
+          @args_to_yield = []
+          @failed_fast = nil
+          @eval_context = nil
+          @yield_receiver_to_implementation_block = false
+
+          @implementation = Implementation.new
+          self.inner_implementation_action = implementation_block
+        end
+        # rubocop:enable Style/ParameterLists
+
+        def expected_args
+          @argument_list_matcher.expected_args
+        end
+
+        def and_yield_receiver_to_implementation
+          @yield_receiver_to_implementation_block = true
+          self
+        end
+
+        def yield_receiver_to_implementation_block?
+          @yield_receiver_to_implementation_block
+        end
+
+        def matches?(message, *args)
+          @message == message && @argument_list_matcher.args_match?(*args)
+        end
+
+        def safe_invoke(parent_stub, *args, &block)
+          invoke_incrementing_actual_calls_by(1, false, parent_stub, *args, &block)
+        end
+
+        def invoke(parent_stub, *args, &block)
+          invoke_incrementing_actual_calls_by(1, true, parent_stub, *args, &block)
+        end
+
+        def invoke_without_incrementing_received_count(parent_stub, *args, &block)
+          invoke_incrementing_actual_calls_by(0, true, parent_stub, *args, &block)
+        end
+
+        def negative?
+          @expected_received_count == 0 && !@at_least
+        end
+
+        def called_max_times?
+          @expected_received_count != :any &&
+            !@at_least &&
+            @expected_received_count > 0 &&
+            @actual_received_count >= @expected_received_count
+        end
+
+        def matches_name_but_not_args(message, *args)
+          @message == message && !@argument_list_matcher.args_match?(*args)
+        end
+
+        def verify_messages_received
+          InsertOntoBacktrace.line(@expected_from) do
+            generate_error unless expected_messages_received? || failed_fast?
+          end
+        end
+
+        def expected_messages_received?
+          ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count?
+        end
+
+        def ensure_expected_ordering_received!
+          @order_group.verify_invocation_order(self) if @ordered
+          true
+        end
+
+        def ignoring_args?
+          @expected_received_count == :any
+        end
+
+        def matches_at_least_count?
+          @at_least && @actual_received_count >= @expected_received_count
+        end
+
+        def matches_at_most_count?
+          @at_most && @actual_received_count <= @expected_received_count
+        end
+
+        def matches_exact_count?
+          @expected_received_count == @actual_received_count
+        end
+
+        def similar_messages
+          @similar_messages ||= []
+        end
+
+        def advise(*args)
+          similar_messages << args
+        end
+
+        def generate_error
+          if similar_messages.empty?
+            @error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *expected_args)
+          else
+            @error_generator.raise_similar_message_args_error(self, *@similar_messages)
+          end
+        end
+
+        def expectation_count_type
+          return :at_least if @at_least
+          return :at_most if @at_most
+          nil
+        end
+
+        def description_for(verb)
+          @error_generator.describe_expectation(
+            verb, @message, @expected_received_count,
+            @actual_received_count, *expected_args
+          )
+        end
+
+        def raise_out_of_order_error
+          @error_generator.raise_out_of_order_error @message
+        end
+
+        def additional_expected_calls
+          return 0 if @expectation_type == :stub || !@exactly
+          @expected_received_count - 1
+        end
+
+        def ordered?
+          @ordered
+        end
+
+        def negative_expectation_for?(message)
+          @message == message && negative?
+        end
+
+        def actual_received_count_matters?
+          @at_least || @at_most || @exactly
+        end
+
+        def increase_actual_received_count!
+          @actual_received_count += 1
+        end
+
+      private
+
+        def invoke_incrementing_actual_calls_by(increment, allowed_to_fail, parent_stub, *args, &block)
+          args.unshift(orig_object) if yield_receiver_to_implementation_block?
+
+          if negative? || (allowed_to_fail && (@exactly || @at_most) && (@actual_received_count == @expected_received_count))
+            @actual_received_count += increment
+            @failed_fast = true
+            # args are the args we actually received, @argument_list_matcher is the
+            # list of args we were expecting
+            @error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *args)
+          end
+
+          @order_group.handle_order_constraint self
+
+          begin
+            if implementation.present?
+              implementation.call(*args, &block)
+            elsif parent_stub
+              parent_stub.invoke(nil, *args, &block)
+            end
+          ensure
+            @actual_received_count += increment
+          end
+        end
+
+        def has_been_invoked?
+          @actual_received_count > 0
+        end
+
+        def raise_already_invoked_error_if_necessary(calling_customization)
+          return unless has_been_invoked?
+
+          error_message = "The message expectation for #{orig_object.inspect}.#{message} has already been invoked " \
+            "and cannot be modified further (e.g. using `#{calling_customization}`). All message expectation " \
+            "customizations must be applied before it is used for the first time."
+
+          raise MockExpectationAlreadyInvokedError, error_message
+        end
+
+        def failed_fast?
+          @failed_fast
+        end
+
+        def set_expected_received_count(relativity, n)
+          @at_least = (relativity == :at_least)
+          @at_most  = (relativity == :at_most)
+          @exactly  = (relativity == :exactly)
+          @expected_received_count = case n
+                                     when Numeric then n
+                                     when :once   then 1
+                                     when :twice  then 2
+                                     when :thrice then 3
+                                     end
+        end
+
+        def initial_implementation_action=(action)
+          implementation.initial_action = action
+        end
+
+        def inner_implementation_action=(action)
+          return unless action
+          warn_about_stub_override if implementation.inner_action
+          implementation.inner_action = action
+        end
+
+        def terminal_implementation_action=(action)
+          implementation.terminal_action = action
+        end
+
+        def warn_about_stub_override
+          RSpec.warning(
+            "You're overriding a previous stub implementation of `#{@message}`. " \
+            "Called from #{CallerFilter.first_non_rspec_line}."
+          )
+        end
+      end
+
+      include ImplementationDetails
+    end
+
+    # Handles the implementation of an `and_yield` declaration.
+    # @private
+    class AndYieldImplementation
+      def initialize(args_to_yield, eval_context, error_generator)
+        @args_to_yield = args_to_yield
+        @eval_context = eval_context
+        @error_generator = error_generator
+      end
+
+      def call(*_args_to_ignore, &block)
+        return if @args_to_yield.empty? && @eval_context.nil?
+
+        @error_generator.raise_missing_block_error @args_to_yield unless block
+        value = nil
+        block_signature = Support::BlockSignature.new(block)
+
+        @args_to_yield.each do |args|
+          unless Support::StrictSignatureVerifier.new(block_signature, args).valid?
+            @error_generator.raise_wrong_arity_error(args, block_signature)
+          end
+
+          value = @eval_context ? @eval_context.instance_exec(*args, &block) : block.call(*args)
+        end
+        value
+      end
+    end
+
+    # Handles the implementation of an `and_return` implementation.
+    # @private
+    class AndReturnImplementation
+      def initialize(values_to_return)
+        @values_to_return = values_to_return
+      end
+
+      def call(*_args_to_ignore, &_block)
+        if @values_to_return.size > 1
+          @values_to_return.shift
+        else
+          @values_to_return.first
+        end
+      end
+    end
+
+    # Represents a configured implementation. Takes into account
+    # any number of sub-implementations.
+    # @private
+    class Implementation
+      attr_accessor :initial_action, :inner_action, :terminal_action
+
+      def call(*args, &block)
+        actions.map do |action|
+          action.call(*args, &block)
+        end.last
+      end
+
+      def present?
+        actions.any?
+      end
+
+    private
+
+      def actions
+        [initial_action, inner_action, terminal_action].compact
+      end
+    end
+
+    # Represents an `and_call_original` implementation.
+    # @private
+    class AndWrapOriginalImplementation
+      def initialize(method, block)
+        @method = method
+        @block = block
+      end
+
+      CannotModifyFurtherError = Class.new(StandardError)
+
+      def initial_action=(_value)
+        raise cannot_modify_further_error
+      end
+
+      def inner_action=(_value)
+        raise cannot_modify_further_error
+      end
+
+      def terminal_action=(_value)
+        raise cannot_modify_further_error
+      end
+
+      def present?
+        true
+      end
+
+      def inner_action
+        true
+      end
+
+      def call(*args, &block)
+        @block.call(@method, *args, &block)
+      end
+
+    private
+
+      def cannot_modify_further_error
+        CannotModifyFurtherError.new "This method has already been configured " \
+          "to call the original implementation, and cannot be modified further."
+      end
+    end
+
+    # Insert original locations into stacktraces
+    #
+    # @private
+    class InsertOntoBacktrace
+      def self.line(location)
+        yield
+      rescue RSpec::Mocks::MockExpectationError => error
+        error.backtrace.insert(0, location)
+        Kernel.raise error
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/method_double.rb b/rspec-mocks/lib/rspec/mocks/method_double.rb
new file mode 100644
index 0000000..d2c0090
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/method_double.rb
@@ -0,0 +1,283 @@
+module RSpec
+  module Mocks
+    # @private
+    class MethodDouble
+      # @private
+      attr_reader :method_name, :object, :expectations, :stubs
+
+      # @private
+      def initialize(object, method_name, proxy)
+        @method_name = method_name
+        @object = object
+        @proxy = proxy
+
+        @original_visibility = nil
+        @method_stasher = InstanceMethodStasher.new(object, method_name)
+        @method_is_proxied = false
+        @expectations = []
+        @stubs = []
+      end
+
+      def original_method
+        # If original method is not present, uses the `method_missing`
+        # handler of the object. This accounts for cases where the user has not
+        # correctly defined `respond_to?`, and also 1.8 which does not provide
+        # method handles for missing methods even if `respond_to?` is correct.
+        @original_method ||=
+          @method_stasher.original_method ||
+          @proxy.original_method_handle_for(method_name) ||
+          Proc.new do |*args, &block|
+            @object.__send__(:method_missing, @method_name, *args, &block)
+          end
+      end
+
+      alias_method :save_original_method!, :original_method
+
+      # @private
+      def visibility
+        @proxy.visibility_for(@method_name)
+      end
+
+      # @private
+      def object_singleton_class
+        class << @object; self; end
+      end
+
+      # @private
+      def configure_method
+        @original_visibility = [visibility, method_name]
+        @method_stasher.stash unless @method_is_proxied
+        define_proxy_method
+      end
+
+      # @private
+      def define_proxy_method
+        return if @method_is_proxied
+
+        save_original_method!
+        definition_target.class_exec(self, method_name, visibility) do |method_double, method_name, visibility|
+          define_method(method_name) do |*args, &block|
+            method_double.proxy_method_invoked(self, *args, &block)
+          end
+          __send__(visibility, method_name)
+        end
+
+        @method_is_proxied = true
+      end
+
+      # The implementation of the proxied method. Subclasses may override this
+      # method to perform additional operations.
+      #
+      # @private
+      def proxy_method_invoked(_obj, *args, &block)
+        @proxy.message_received method_name, *args, &block
+      end
+
+      # @private
+      def restore_original_method
+        return show_frozen_warning if object_singleton_class.frozen?
+        return unless @method_is_proxied
+
+        remove_method_from_definition_target
+        @method_stasher.restore if @method_stasher.method_is_stashed?
+        restore_original_visibility
+
+        @method_is_proxied = false
+      end
+
+      # @private
+      def show_frozen_warning
+        RSpec.warn_with(
+          "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` " \
+          "method on #{@object.inspect} because it has been frozen.  If you reuse this " \
+          "object, `#{@method_name}` will continue to respond with its stub implementation.",
+          :call_site                      => nil,
+          :use_spec_location_as_call_site => true
+        )
+      end
+
+      # @private
+      def restore_original_visibility
+        return unless @original_visibility &&
+          MethodReference.method_defined_at_any_visibility?(object_singleton_class, @method_name)
+
+        object_singleton_class.__send__(*@original_visibility)
+      end
+
+      # @private
+      def verify
+        expectations.each { |e| e.verify_messages_received }
+      end
+
+      # @private
+      def reset
+        restore_original_method
+        clear
+      end
+
+      # @private
+      def clear
+        expectations.clear
+        stubs.clear
+      end
+
+      # The type of message expectation to create has been extracted to its own
+      # method so that subclasses can override it.
+      #
+      # @private
+      def message_expectation_class
+        MessageExpectation
+      end
+
+      # @private
+      def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation)
+        configure_method
+        expectation = message_expectation_class.new(error_generator, expectation_ordering,
+                                                    expected_from, self, :expectation, opts, &implementation)
+        expectations << expectation
+        expectation
+      end
+
+      # @private
+      def build_expectation(error_generator, expectation_ordering)
+        expected_from = IGNORED_BACKTRACE_LINE
+        message_expectation_class.new(error_generator, expectation_ordering, expected_from, self)
+      end
+
+      # @private
+      def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation)
+        configure_method
+        stub = message_expectation_class.new(error_generator, expectation_ordering, expected_from,
+                                             self, :stub, opts, &implementation)
+        stubs.unshift stub
+        stub
+      end
+
+      # A simple stub can only return a concrete value for a message, and
+      # cannot match on arguments. It is used as an optimization over
+      # `add_stub` / `add_expectation` where it is known in advance that this
+      # is all that will be required of a stub, such as when passing attributes
+      # to the `double` example method. They do not stash or restore existing method
+      # definitions.
+      #
+      # @private
+      def add_simple_stub(method_name, response)
+        setup_simple_method_double method_name, response, stubs
+      end
+
+      # @private
+      def add_simple_expectation(method_name, response, error_generator, backtrace_line)
+        setup_simple_method_double method_name, response, expectations, error_generator, backtrace_line
+      end
+
+      # @private
+      def setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil)
+        define_proxy_method
+
+        me = SimpleMessageExpectation.new(method_name, response, error_generator, backtrace_line)
+        collection.unshift me
+        me
+      end
+
+      # @private
+      def add_default_stub(*args, &implementation)
+        return if stubs.any?
+        add_stub(*args, &implementation)
+      end
+
+      # @private
+      def remove_stub
+        raise_method_not_stubbed_error if stubs.empty?
+        remove_stub_if_present
+      end
+
+      # @private
+      def remove_stub_if_present
+        expectations.empty? ? reset : stubs.clear
+      end
+
+      # @private
+      def raise_method_not_stubbed_error
+        raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed"
+      end
+
+      # In Ruby 2.0.0 and above prepend will alter the method lookup chain.
+      # We use an object's singleton class to define method doubles upon,
+      # however if the object has had it's singleton class (as opposed to
+      # it's actual class) prepended too then the the method lookup chain
+      # will look in the prepended module first, **before** the singleton
+      # class.
+      #
+      # This code works around that by providing a mock definition target
+      # that is either the singleton class, or if necessary, a prepended module
+      # of our own.
+      #
+      if Support::RubyFeatures.module_prepends_supported?
+
+        private
+
+        # We subclass `Module` in order to be able to easily detect our prepended module.
+        RSpecPrependedModule = Class.new(Module)
+
+        def definition_target
+          @definition_target ||= usable_rspec_prepended_module || object_singleton_class
+        end
+
+        def usable_rspec_prepended_module
+          @proxy.prepended_modules_of_singleton_class.each do |mod|
+            # If we have one of our modules prepended before one of the user's
+            # modules that defines the method, use that, since our module's
+            # definition will take precedence.
+            return mod if RSpecPrependedModule === mod
+
+            # If we hit a user module with the method defined first,
+            # we must create a new prepend module, even if one exists later,
+            # because ours will only take precedence if it comes first.
+            return new_rspec_prepended_module if mod.method_defined?(method_name)
+          end
+
+          nil
+        end
+
+        def new_rspec_prepended_module
+          RSpecPrependedModule.new.tap do |mod|
+            object_singleton_class.__send__ :prepend, mod
+          end
+        end
+
+      else
+
+        private
+
+        def definition_target
+          object_singleton_class
+        end
+
+      end
+
+    private
+
+      def remove_method_from_definition_target
+        definition_target.__send__(:remove_method, @method_name)
+      rescue NameError
+        # This can happen when the method has been monkeyed with by
+        # something outside RSpec. This happens, for example, when
+        # `file.write` has been stubbed, and then `file.reopen(other_io)`
+        # is later called, as `File#reopen` appears to redefine `write`.
+        #
+        # Note: we could avoid rescuing this by checking
+        # `definition_target.instance_method(@method_name).owner == definition_target`,
+        # saving us from the cost of the expensive exception, but this error is
+        # extremely rare (it was discovered on 2014-12-30, only happens on
+        # RUBY_VERSION < 2.0 and our spec suite only hits this condition once),
+        # so we'd rather avoid the cost of that check for every method double,
+        # and risk the rare situation where this exception will get raised.
+        RSpec.warn_with(
+          "WARNING: RSpec could not fully restore #{@object.inspect}." \
+          "#{@method_name}, possibly because the method has been redefined " \
+          "by something outside of RSpec."
+        )
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/method_reference.rb b/rspec-mocks/lib/rspec/mocks/method_reference.rb
new file mode 100644
index 0000000..21896bf
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/method_reference.rb
@@ -0,0 +1,155 @@
+module RSpec
+  module Mocks
+    # Represents a method on an object that may or may not be defined.
+    # The method may be an instance method on a module or a method on
+    # any object.
+    #
+    # @private
+    class MethodReference
+      def initialize(object_reference, method_name)
+        @object_reference = object_reference
+        @method_name = method_name
+      end
+
+      # A method is implemented if sending the message does not result in
+      # a `NoMethodError`. It might be dynamically implemented by
+      # `method_missing`.
+      def implemented?
+        @object_reference.when_loaded do |m|
+          method_implemented?(m)
+        end
+      end
+
+      # Returns true if we definitively know that sending the method
+      # will result in a `NoMethodError`.
+      #
+      # This is not simply the inverse of `implemented?`: there are
+      # cases when we don't know if a method is implemented and
+      # both `implemented?` and `unimplemented?` will return false.
+      def unimplemented?
+        @object_reference.when_loaded do |_m|
+          return !implemented?
+        end
+
+        # If it's not loaded, then it may be implemented but we can't check.
+        false
+      end
+
+      # A method is defined if we are able to get a `Method` object for it.
+      # In that case, we can assert against metadata like the arity.
+      def defined?
+        @object_reference.when_loaded do |m|
+          method_defined?(m)
+        end
+      end
+
+      def with_signature
+        return unless (original = original_method)
+        yield Support::MethodSignature.new(original)
+      end
+
+      def visibility
+        @object_reference.when_loaded do |m|
+          return visibility_from(m)
+        end
+
+        # When it's not loaded, assume it's public. We don't want to
+        # wrongly treat the method as private.
+        :public
+      end
+
+    private
+
+      def original_method
+        @object_reference.when_loaded do |m|
+          self.defined? && find_method(m)
+        end
+      end
+
+      def self.instance_method_visibility_for(klass, method_name)
+        if klass.public_method_defined?(method_name)
+          :public
+        elsif klass.private_method_defined?(method_name)
+          :private
+        elsif klass.protected_method_defined?(method_name)
+          :protected
+        end
+      end
+
+      class << self
+        alias method_defined_at_any_visibility? instance_method_visibility_for
+      end
+
+      def self.method_visibility_for(object, method_name)
+        instance_method_visibility_for(class << object; self; end, method_name).tap do |vis|
+          # If the method is not defined on the class, `instance_method_visibility_for`
+          # returns `nil`. However, it may be handled dynamically by `method_missing`,
+          # so here we check `respond_to` (passing false to not check private methods).
+          #
+          # This only considers the public case, but I don't think it's possible to
+          # write `method_missing` in such a way that it handles a dynamic message
+          # with private or protected visibility. Ruby doesn't provide you with
+          # the caller info.
+          return :public if vis.nil? && object.respond_to?(method_name, false)
+        end
+      end
+    end
+
+    # @private
+    class InstanceMethodReference < MethodReference
+    private
+
+      def method_implemented?(mod)
+        MethodReference.method_defined_at_any_visibility?(mod, @method_name)
+      end
+
+      # Ideally, we'd use `respond_to?` for `method_implemented?` but we need a
+      # reference to an instance to do that and we don't have one.  Note that
+      # we may get false negatives: if the method is implemented via
+      # `method_missing`, we'll return `false` even though it meets our
+      # definition of "implemented". However, it's the best we can do.
+      alias method_defined? method_implemented?
+
+      # works around the fact that repeated calls for method parameters will
+      # falsely return empty arrays on JRuby in certain circumstances, this
+      # is necessary here because we can't dup/clone UnboundMethods.
+      #
+      # This is necessary due to a bug in JRuby prior to 1.7.5 fixed in:
+      # https://github.com/jruby/jruby/commit/99a0613fe29935150d76a9a1ee4cf2b4f63f4a27
+      if RUBY_PLATFORM == 'java' && JRUBY_VERSION.split('.')[-1].to_i < 5
+        def find_method(mod)
+          mod.dup.instance_method(@method_name)
+        end
+      else
+        def find_method(mod)
+          mod.instance_method(@method_name)
+        end
+      end
+
+      def visibility_from(mod)
+        MethodReference.instance_method_visibility_for(mod, @method_name)
+      end
+    end
+
+    # @private
+    class ObjectMethodReference < MethodReference
+    private
+
+      def method_implemented?(object)
+        object.respond_to?(@method_name, true)
+      end
+
+      def method_defined?(object)
+        (class << object; self; end).method_defined?(@method_name)
+      end
+
+      def find_method(object)
+        object.method(@method_name)
+      end
+
+      def visibility_from(object)
+        MethodReference.method_visibility_for(object, @method_name)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/mutate_const.rb b/rspec-mocks/lib/rspec/mocks/mutate_const.rb
new file mode 100644
index 0000000..7cb1c92
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/mutate_const.rb
@@ -0,0 +1,335 @@
+RSpec::Support.require_rspec_support 'recursive_const_methods'
+
+module RSpec
+  module Mocks
+    # Provides information about constants that may (or may not)
+    # have been mutated by rspec-mocks.
+    class Constant
+      extend Support::RecursiveConstMethods
+
+      # @api private
+      def initialize(name)
+        @name = name
+        @previously_defined = false
+        @stubbed = false
+        @hidden = false
+        @valid_name = true
+        yield self if block_given?
+      end
+
+      # @return [String] The fully qualified name of the constant.
+      attr_reader :name
+
+      # @return [Object, nil] The original value (e.g. before it
+      #   was mutated by rspec-mocks) of the constant, or
+      #   nil if the constant was not previously defined.
+      attr_accessor :original_value
+
+      # @private
+      attr_writer :previously_defined, :stubbed, :hidden, :valid_name
+
+      # @return [Boolean] Whether or not the constant was defined
+      #   before the current example.
+      def previously_defined?
+        @previously_defined
+      end
+
+      # @return [Boolean] Whether or not rspec-mocks has mutated
+      #   (stubbed or hidden) this constant.
+      def mutated?
+        @stubbed || @hidden
+      end
+
+      # @return [Boolean] Whether or not rspec-mocks has stubbed
+      #   this constant.
+      def stubbed?
+        @stubbed
+      end
+
+      # @return [Boolean] Whether or not rspec-mocks has hidden
+      #   this constant.
+      def hidden?
+        @hidden
+      end
+
+      # @return [Boolean] Whether or not the provided constant name
+      #   is a valid Ruby constant name.
+      def valid_name?
+        @valid_name
+      end
+
+      # The default `to_s` isn't very useful, so a custom version is provided.
+      def to_s
+        "#<#{self.class.name} #{name}>"
+      end
+      alias inspect to_s
+
+      # @private
+      def self.unmutated(name)
+        previously_defined = recursive_const_defined?(name)
+      rescue NameError
+        new(name) do |c|
+          c.valid_name = false
+        end
+      else
+        new(name) do |const|
+          const.previously_defined = previously_defined
+          const.original_value = recursive_const_get(name) if previously_defined
+        end
+      end
+
+      # Queries rspec-mocks to find out information about the named constant.
+      #
+      # @param [String] name the name of the constant
+      # @return [Constant] an object contaning information about the named
+      #   constant.
+      def self.original(name)
+        mutator = ::RSpec::Mocks.space.constant_mutator_for(name)
+        mutator ? mutator.to_constant : unmutated(name)
+      end
+    end
+
+    # Provides a means to stub constants.
+    class ConstantMutator
+      extend Support::RecursiveConstMethods
+
+      # Stubs a constant.
+      #
+      # @param (see ExampleMethods#stub_const)
+      # @option (see ExampleMethods#stub_const)
+      # @return (see ExampleMethods#stub_const)
+      #
+      # @see ExampleMethods#stub_const
+      # @note It's recommended that you use `stub_const` in your
+      #  examples. This is an alternate public API that is provided
+      #  so you can stub constants in other contexts (e.g. helper
+      #  classes).
+      def self.stub(constant_name, value, options={})
+        mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const)
+                    DefinedConstantReplacer
+                  else
+                    UndefinedConstantSetter
+                  end
+
+        mutate(mutator.new(constant_name, value, options[:transfer_nested_constants]))
+        value
+      end
+
+      # Hides a constant.
+      #
+      # @param (see ExampleMethods#hide_const)
+      #
+      # @see ExampleMethods#hide_const
+      # @note It's recommended that you use `hide_const` in your
+      #  examples. This is an alternate public API that is provided
+      #  so you can hide constants in other contexts (e.g. helper
+      #  classes).
+      def self.hide(constant_name)
+        mutate(ConstantHider.new(constant_name, nil, {}))
+        nil
+      end
+
+      # Contains common functionality used by all of the constant mutators.
+      #
+      # @private
+      class BaseMutator
+        include Support::RecursiveConstMethods
+
+        attr_reader :original_value, :full_constant_name
+
+        def initialize(full_constant_name, mutated_value, transfer_nested_constants)
+          @full_constant_name        = normalize_const_name(full_constant_name)
+          @mutated_value             = mutated_value
+          @transfer_nested_constants = transfer_nested_constants
+          @context_parts             = @full_constant_name.split('::')
+          @const_name                = @context_parts.pop
+          @reset_performed           = false
+        end
+
+        def to_constant
+          const = Constant.new(full_constant_name)
+          const.original_value = original_value
+
+          const
+        end
+
+        def idempotently_reset
+          reset unless @reset_performed
+          @reset_performed = true
+        end
+      end
+
+      # Hides a defined constant for the duration of an example.
+      #
+      # @private
+      class ConstantHider < BaseMutator
+        def mutate
+          return unless (@defined = recursive_const_defined?(full_constant_name))
+          @context = recursive_const_get(@context_parts.join('::'))
+          @original_value = get_const_defined_on(@context, @const_name)
+
+          @context.__send__(:remove_const, @const_name)
+        end
+
+        def to_constant
+          return Constant.unmutated(full_constant_name) unless @defined
+
+          const = super
+          const.hidden = true
+          const.previously_defined = true
+
+          const
+        end
+
+        def reset
+          return unless @defined
+          @context.const_set(@const_name, @original_value)
+        end
+      end
+
+      # Replaces a defined constant for the duration of an example.
+      #
+      # @private
+      class DefinedConstantReplacer < BaseMutator
+        def initialize(*args)
+          super
+          @constants_to_transfer = []
+        end
+
+        def mutate
+          @context = recursive_const_get(@context_parts.join('::'))
+          @original_value = get_const_defined_on(@context, @const_name)
+
+          @constants_to_transfer = verify_constants_to_transfer!
+
+          @context.__send__(:remove_const, @const_name)
+          @context.const_set(@const_name, @mutated_value)
+
+          transfer_nested_constants
+        end
+
+        def to_constant
+          const = super
+          const.stubbed = true
+          const.previously_defined = true
+
+          const
+        end
+
+        def reset
+          @constants_to_transfer.each do |const|
+            @mutated_value.__send__(:remove_const, const)
+          end
+
+          @context.__send__(:remove_const, @const_name)
+          @context.const_set(@const_name, @original_value)
+        end
+
+        def transfer_nested_constants
+          @constants_to_transfer.each do |const|
+            @mutated_value.const_set(const, get_const_defined_on(original_value, const))
+          end
+        end
+
+        def verify_constants_to_transfer!
+          return [] unless should_transfer_nested_constants?
+
+          { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description|
+            next if value.respond_to?(:constants)
+
+            raise ArgumentError,
+                  "Cannot transfer nested constants for #{@full_constant_name} " \
+                  "since #{description} is not a class or module and only classes " \
+                  "and modules support nested constants."
+          end
+
+          if Array === @transfer_nested_constants
+            @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7'
+            undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value)
+
+            if undefined_constants.any?
+              available_constants = constants_defined_on(@original_value) - @transfer_nested_constants
+              raise ArgumentError,
+                    "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " \
+                    "for #{@full_constant_name} since they are not defined. Did you mean " \
+                    "#{available_constants.join(' or ')}?"
+            end
+
+            @transfer_nested_constants
+          else
+            constants_defined_on(@original_value)
+          end
+        end
+
+        def should_transfer_nested_constants?
+          return true  if @transfer_nested_constants
+          return false unless RSpec::Mocks.configuration.transfer_nested_constants?
+          @original_value.respond_to?(:constants) && @mutated_value.respond_to?(:constants)
+        end
+      end
+
+      # Sets an undefined constant for the duration of an example.
+      #
+      # @private
+      class UndefinedConstantSetter < BaseMutator
+        def mutate
+          @parent = @context_parts.inject(Object) do |klass, name|
+            if const_defined_on?(klass, name)
+              get_const_defined_on(klass, name)
+            else
+              ConstantMutator.stub(name_for(klass, name), Module.new)
+            end
+          end
+
+          @parent.const_set(@const_name, @mutated_value)
+        end
+
+        def to_constant
+          const = super
+          const.stubbed = true
+          const.previously_defined = false
+
+          const
+        end
+
+        def reset
+          @parent.__send__(:remove_const, @const_name)
+        end
+
+      private
+
+        def name_for(parent, name)
+          root = if parent == Object
+                   ''
+                 else
+                   parent.name
+                 end
+          root + '::' + name
+        end
+      end
+
+      # Uses the mutator to mutate (stub or hide) a constant. Ensures that
+      # the mutator is correctly registered so it can be backed out at the end
+      # of the test.
+      #
+      # @private
+      def self.mutate(mutator)
+        ::RSpec::Mocks.space.register_constant_mutator(mutator)
+        mutator.mutate
+      end
+
+      # Used internally by the constant stubbing to raise a helpful
+      # error when a constant like "A::B::C" is stubbed and A::B is
+      # not a module (and thus, it's impossible to define "A::B::C"
+      # since only modules can have nested constants).
+      #
+      # @api private
+      def self.raise_on_invalid_const
+        lambda do |const_name, failed_name|
+          raise "Cannot stub constant #{failed_name} on #{const_name} " \
+                "since #{const_name} is not a module."
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/object_reference.rb b/rspec-mocks/lib/rspec/mocks/object_reference.rb
new file mode 100644
index 0000000..cce2c33
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/object_reference.rb
@@ -0,0 +1,149 @@
+module RSpec
+  module Mocks
+    # @private
+    class ObjectReference
+      # Returns an appropriate Object or Module reference based
+      # on the given argument.
+      def self.for(object_module_or_name, allow_direct_object_refs=false)
+        case object_module_or_name
+        when Module
+          if anonymous_module?(object_module_or_name)
+            DirectObjectReference.new(object_module_or_name)
+          else
+            # Use a `NamedObjectReference` if it has a name because this
+            # will use the original value of the constant in case it has
+            # been stubbed.
+            NamedObjectReference.new(name_of(object_module_or_name))
+          end
+        when String
+          NamedObjectReference.new(object_module_or_name)
+        else
+          if allow_direct_object_refs
+            DirectObjectReference.new(object_module_or_name)
+          else
+            raise ArgumentError,
+                  "Module or String expected, got #{object_module_or_name.inspect}"
+          end
+        end
+      end
+
+      if Module.new.name.nil?
+        def self.anonymous_module?(mod)
+          !name_of(mod)
+        end
+      else # 1.8.7
+        def self.anonymous_module?(mod)
+          name_of(mod) == ""
+        end
+      end
+      private_class_method :anonymous_module?
+
+      def self.name_of(mod)
+        MODULE_NAME_METHOD.bind(mod).call
+      end
+      private_class_method :name_of
+
+      # @private
+      MODULE_NAME_METHOD = Module.instance_method(:name)
+    end
+
+    # An implementation of rspec-mocks' reference interface.
+    # Used when an object is passed to {ExampleMethods#object_double}, or
+    # an anonymous class or module is passed to {ExampleMethods#instance_double}
+    # or {ExampleMethods#class_double}.
+    # Represents a reference to that object.
+    # @see NamedObjectReference
+    class DirectObjectReference
+      # @param object [Object] the object to which this refers
+      def initialize(object)
+        @object = object
+      end
+
+      # @return [String] the object's description (via `#inspect`).
+      def description
+        @object.inspect
+      end
+
+      # Defined for interface parity with the other object reference
+      # implementations. Raises an `ArgumentError` to indicate that `as_stubbed_const`
+      # is invalid when passing an object argument to `object_double`.
+      def const_to_replace
+        raise ArgumentError,
+              "Can not perform constant replacement with an anonymous object."
+      end
+
+      # The target of the verifying double (the object itself).
+      #
+      # @return [Object]
+      def target
+        @object
+      end
+
+      # Always returns true for an object as the class is defined.
+      #
+      # @return [true]
+      def defined?
+        true
+      end
+
+      # Yields if the reference target is loaded, providing a generic mechanism
+      # to optionally run a bit of code only when a reference's target is
+      # loaded.
+      #
+      # This specific implementation always yields because direct references
+      # are always loaded.
+      #
+      # @yield [Object] the target of this reference.
+      def when_loaded
+        yield @object
+      end
+    end
+
+    # An implementation of rspec-mocks' reference interface.
+    # Used when a string is passed to {ExampleMethods#object_double},
+    # and when a string, named class or named module is passed to
+    # {ExampleMethods#instance_double}, or {ExampleMethods#class_double}.
+    # Represents a reference to the object named (via a constant lookup)
+    # by the string.
+    # @see DirectObjectReference
+    class NamedObjectReference
+      # @param const_name [String] constant name
+      def initialize(const_name)
+        @const_name = const_name
+      end
+
+      # @return [Boolean] true if the named constant is defined, false otherwise.
+      def defined?
+        !!object
+      end
+
+      # @return [String] the constant name to replace with a double.
+      def const_to_replace
+        @const_name
+      end
+      alias description const_to_replace
+
+      # @return [Object, nil] the target of the verifying double (the named object), or
+      #   nil if it is not defined.
+      def target
+        object
+      end
+
+      # Yields if the reference target is loaded, providing a generic mechanism
+      # to optionally run a bit of code only when a reference's target is
+      # loaded.
+      #
+      # @yield [Object] the target object
+      def when_loaded
+        yield object if object
+      end
+
+    private
+
+      def object
+        return @object if defined?(@object)
+        @object = Constant.original(@const_name).original_value
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/order_group.rb b/rspec-mocks/lib/rspec/mocks/order_group.rb
new file mode 100644
index 0000000..a994799
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/order_group.rb
@@ -0,0 +1,81 @@
+module RSpec
+  module Mocks
+    # @private
+    class OrderGroup
+      def initialize
+        @expectations = []
+        @invocation_order = []
+        @index = 0
+      end
+
+      # @private
+      def register(expectation)
+        @expectations << expectation
+      end
+
+      def invoked(message)
+        @invocation_order << message
+      end
+
+      # @private
+      def ready_for?(expectation)
+        remaining_expectations.find(&:ordered?) == expectation
+      end
+
+      # @private
+      def consume
+        remaining_expectations.each_with_index do |expectation, index|
+          next unless expectation.ordered?
+
+          @index += index + 1
+          return expectation
+        end
+        nil
+      end
+
+      # @private
+      def handle_order_constraint(expectation)
+        return unless expectation.ordered? && remaining_expectations.include?(expectation)
+        return consume if ready_for?(expectation)
+        expectation.raise_out_of_order_error
+      end
+
+      def verify_invocation_order(expectation)
+        expectation.raise_out_of_order_error unless expectations_invoked_in_order?
+        true
+      end
+
+      def clear
+        @index = 0
+        @invocation_order.clear
+        @expectations.clear
+      end
+
+      def empty?
+        @expectations.empty?
+      end
+
+    private
+
+      def remaining_expectations
+        @expectations[@index..-1] || []
+      end
+
+      def expectations_invoked_in_order?
+        invoked_expectations == expected_invocations
+      end
+
+      def invoked_expectations
+        @expectations.select { |e| e.ordered? && @invocation_order.include?(e) }
+      end
+
+      def expected_invocations
+        @invocation_order.map { |invocation| expectation_for(invocation) }.compact
+      end
+
+      def expectation_for(message)
+        @expectations.find { |e| message == e }
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/proxy.rb b/rspec-mocks/lib/rspec/mocks/proxy.rb
new file mode 100644
index 0000000..b936a3a
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/proxy.rb
@@ -0,0 +1,431 @@
+module RSpec
+  module Mocks
+    # @private
+    class Proxy
+      SpecificMessage = Struct.new(:object, :message, :args) do
+        def ==(expectation)
+          expectation.orig_object == object && expectation.matches?(message, *args)
+        end
+      end
+
+      # @private
+      def ensure_implemented(*_args)
+        # noop for basic proxies, see VerifyingProxy for behaviour.
+      end
+
+      # @private
+      def initialize(object, order_group, name=nil, options={})
+        @object = object
+        @order_group = order_group
+        @name = name
+        @error_generator = ErrorGenerator.new(object, name)
+        @messages_received = []
+        @options = options
+        @null_object = false
+        @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) }
+      end
+
+      # @private
+      attr_reader :object
+
+      # @private
+      def null_object?
+        @null_object
+      end
+
+      # @private
+      # Tells the object to ignore any messages that aren't explicitly set as
+      # stubs or message expectations.
+      def as_null_object
+        @null_object = true
+        @object
+      end
+
+      # @private
+      def original_method_handle_for(_message)
+        nil
+      end
+
+      # @private
+      def add_message_expectation(method_name, opts={}, &block)
+        location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line }
+        meth_double = method_double_for(method_name)
+
+        if null_object? && !block
+          meth_double.add_default_stub(@error_generator, @order_group, location, opts) do
+            @object
+          end
+        end
+
+        meth_double.add_expectation @error_generator, @order_group, location, opts, &block
+      end
+
+      # @private
+      def add_simple_expectation(method_name, response, location)
+        method_double_for(method_name).add_simple_expectation method_name, response, @error_generator, location
+      end
+
+      # @private
+      def build_expectation(method_name)
+        meth_double = method_double_for(method_name)
+
+        meth_double.build_expectation(
+          @error_generator,
+          @order_group
+        )
+      end
+
+      # @private
+      def replay_received_message_on(expectation, &block)
+        expected_method_name = expectation.message
+        meth_double = method_double_for(expected_method_name)
+
+        if meth_double.expectations.any?
+          @error_generator.raise_expectation_on_mocked_method(expected_method_name)
+        end
+
+        unless null_object? || meth_double.stubs.any?
+          @error_generator.raise_expectation_on_unstubbed_method(expected_method_name)
+        end
+
+        @messages_received.each do |(actual_method_name, args, _)|
+          next unless expectation.matches?(actual_method_name, *args)
+
+          expectation.safe_invoke(nil)
+          block.call(*args) if block
+        end
+      end
+
+      # @private
+      def check_for_unexpected_arguments(expectation)
+        @messages_received.each do |(method_name, args, _)|
+          next unless expectation.matches_name_but_not_args(method_name, *args)
+
+          raise_unexpected_message_args_error(expectation, *args)
+        end
+      end
+
+      # @private
+      def add_stub(method_name, opts={}, &implementation)
+        location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line }
+        method_double_for(method_name).add_stub @error_generator, @order_group, location, opts, &implementation
+      end
+
+      # @private
+      def add_simple_stub(method_name, response)
+        method_double_for(method_name).add_simple_stub method_name, response
+      end
+
+      # @private
+      def remove_stub(method_name)
+        method_double_for(method_name).remove_stub
+      end
+
+      # @private
+      def remove_stub_if_present(method_name)
+        method_double_for(method_name).remove_stub_if_present
+      end
+
+      # @private
+      def verify
+        @method_doubles.each_value { |d| d.verify }
+      end
+
+      # @private
+      def reset
+        @messages_received.clear
+      end
+
+      # @private
+      def received_message?(method_name, *args, &block)
+        @messages_received.any? { |array| array == [method_name, args, block] }
+      end
+
+      # @private
+      def has_negative_expectation?(message)
+        method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) }
+      end
+
+      # @private
+      def record_message_received(message, *args, &block)
+        @order_group.invoked SpecificMessage.new(object, message, args)
+        @messages_received << [message, args, block]
+      end
+
+      # @private
+      def message_received(message, *args, &block)
+        record_message_received message, *args, &block
+
+        expectation = find_matching_expectation(message, *args)
+        stub = find_matching_method_stub(message, *args)
+
+        if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
+          expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters?
+          if (expectation = find_almost_matching_expectation(message, *args))
+            expectation.advise(*args) unless expectation.expected_messages_received?
+          end
+          stub.invoke(nil, *args, &block)
+        elsif expectation
+          expectation.invoke(stub, *args, &block)
+        elsif (expectation = find_almost_matching_expectation(message, *args))
+          expectation.advise(*args) if null_object? unless expectation.expected_messages_received?
+
+          if null_object? || !has_negative_expectation?(message)
+            raise_unexpected_message_args_error(expectation, *args)
+          end
+        elsif (stub = find_almost_matching_stub(message, *args))
+          stub.advise(*args)
+          raise_missing_default_stub_error(stub, *args)
+        elsif Class === @object
+          @object.superclass.__send__(message, *args, &block)
+        else
+          @object.__send__(:method_missing, message, *args, &block)
+        end
+      end
+
+      # @private
+      def raise_unexpected_message_error(method_name, *args)
+        @error_generator.raise_unexpected_message_error method_name, *args
+      end
+
+      # @private
+      def raise_unexpected_message_args_error(expectation, *args)
+        @error_generator.raise_unexpected_message_args_error(expectation, *args)
+      end
+
+      # @private
+      def raise_missing_default_stub_error(expectation, *args)
+        @error_generator.raise_missing_default_stub_error(expectation, *args)
+      end
+
+      # @private
+      def visibility_for(_method_name)
+        # This is the default (for test doubles). Subclasses override this.
+        :public
+      end
+
+      if Support::RubyFeatures.module_prepends_supported?
+        def self.prepended_modules_of(klass)
+          ancestors = klass.ancestors
+
+          # `|| 0` is necessary for Ruby 2.0, where the singleton class
+          # is only in the ancestor list when there are prepended modules.
+          singleton_index = ancestors.index(klass) || 0
+
+          ancestors[0, singleton_index]
+        end
+
+        def prepended_modules_of_singleton_class
+          @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class)
+        end
+      end
+
+    private
+
+      def method_double_for(message)
+        @method_doubles[message.to_sym]
+      end
+
+      def find_matching_expectation(method_name, *args)
+        find_best_matching_expectation_for(method_name) do |expectation|
+          expectation.matches?(method_name, *args)
+        end
+      end
+
+      def find_almost_matching_expectation(method_name, *args)
+        find_best_matching_expectation_for(method_name) do |expectation|
+          expectation.matches_name_but_not_args(method_name, *args)
+        end
+      end
+
+      def find_best_matching_expectation_for(method_name)
+        first_match = nil
+
+        method_double_for(method_name).expectations.each do |expectation|
+          next unless yield expectation
+          return expectation unless expectation.called_max_times?
+          first_match ||= expectation
+        end
+
+        first_match
+      end
+
+      def find_matching_method_stub(method_name, *args)
+        method_double_for(method_name).stubs.find { |stub| stub.matches?(method_name, *args) }
+      end
+
+      def find_almost_matching_stub(method_name, *args)
+        method_double_for(method_name).stubs.find { |stub| stub.matches_name_but_not_args(method_name, *args) }
+      end
+    end
+
+    # @private
+    class TestDoubleProxy < Proxy
+      def reset
+        @method_doubles.clear
+        object.__disallow_further_usage!
+        super
+      end
+    end
+
+    # @private
+    class PartialDoubleProxy < Proxy
+      def original_method_handle_for(message)
+        if any_instance_class_recorder_observing_method?(@object.class, message)
+          message = ::RSpec::Mocks.space.
+            any_instance_recorder_for(@object.class).
+            build_alias_method_name(message)
+        end
+
+        ::RSpec::Support.method_handle_for(@object, message)
+      rescue NameError
+        nil
+      end
+
+      # @private
+      def add_simple_expectation(method_name, response, location)
+        method_double_for(method_name).configure_method
+        super
+      end
+
+      # @private
+      def add_simple_stub(method_name, response)
+        method_double_for(method_name).configure_method
+        super
+      end
+
+      # @private
+      def visibility_for(method_name)
+        # We fall back to :public because by default we allow undefined methods
+        # to be stubbed, and when we do so, we make them public.
+        MethodReference.method_visibility_for(@object, method_name) || :public
+      end
+
+      def reset
+        @method_doubles.each_value { |d| d.reset }
+        super
+      end
+
+      def message_received(message, *args, &block)
+        RSpec::Mocks.space.any_instance_recorders_from_ancestry_of(object).each do |subscriber|
+          subscriber.notify_received_message(object, message, args, block)
+        end
+        super
+      end
+
+    private
+
+      def any_instance_class_recorder_observing_method?(klass, method_name)
+        only_return_existing = true
+        recorder = ::RSpec::Mocks.space.any_instance_recorder_for(klass, only_return_existing)
+        return true if recorder && recorder.already_observing?(method_name)
+
+        superklass = klass.superclass
+        return false if superklass.nil?
+        any_instance_class_recorder_observing_method?(superklass, method_name)
+      end
+    end
+
+    # @private
+    # When we mock or stub a method on a class, we have to treat it a bit different,
+    # because normally singleton method definitions only affect the object on which
+    # they are defined, but on classes they affect subclasses, too. As a result,
+    # we need some special handling to get the original method.
+    module PartialClassDoubleProxyMethods
+      def initialize(source_space, *args)
+        @source_space = source_space
+        super(*args)
+      end
+
+      # Consider this situation:
+      #
+      #   class A; end
+      #   class B < A; end
+      #
+      #   allow(A).to receive(:new)
+      #   expect(B).to receive(:new).and_call_original
+      #
+      # When getting the original definition for `B.new`, we cannot rely purely on
+      # using `B.method(:new)` before our redefinition is defined on `B`, because
+      # `B.method(:new)` will return a method that will execute the stubbed version
+      # of the method on `A` since singleton methods on classes are in the lookup
+      # hierarchy.
+      #
+      # To do it properly, we need to find the original definition of `new` from `A`
+      # from _before_ `A` was stubbed, and we need to rebind it to `B` so that it will
+      # run with the proper `self`.
+      #
+      # That's what this method (together with `original_unbound_method_handle_from_ancestor_for`)
+      # does.
+      def original_method_handle_for(message)
+        unbound_method = superclass_proxy &&
+          superclass_proxy.original_unbound_method_handle_from_ancestor_for(message.to_sym)
+
+        return super unless unbound_method
+        unbound_method.bind(object)
+      end
+
+    protected
+
+      def original_unbound_method_handle_from_ancestor_for(message)
+        method_double = @method_doubles.fetch(message) do
+          # The fact that there is no method double for this message indicates
+          # that it has not been redefined by rspec-mocks. We need to continue
+          # looking up the ancestor chain.
+          return superclass_proxy &&
+            superclass_proxy.original_unbound_method_handle_from_ancestor_for(message)
+        end
+
+        method_double.original_method.unbind
+      end
+
+      def superclass_proxy
+        return @superclass_proxy if defined?(@superclass_proxy)
+
+        if (superclass = object.superclass)
+          @superclass_proxy = @source_space.proxy_for(superclass)
+        else
+          @superclass_proxy = nil
+        end
+      end
+    end
+
+    # @private
+    class PartialClassDoubleProxy < PartialDoubleProxy
+      include PartialClassDoubleProxyMethods
+    end
+
+    # @private
+    class ProxyForNil < PartialDoubleProxy
+      def initialize(order_group)
+        @warn_about_expectations = true
+        super(nil, order_group)
+      end
+
+      attr_accessor :warn_about_expectations
+      alias warn_about_expectations? warn_about_expectations
+
+      def add_message_expectation(method_name, opts={}, &block)
+        warn(method_name) if warn_about_expectations?
+        super
+      end
+
+      def add_negative_message_expectation(location, method_name, &implementation)
+        warn(method_name) if warn_about_expectations?
+        super
+      end
+
+      def add_stub(method_name, opts={}, &implementation)
+        warn(method_name) if warn_about_expectations?
+        super
+      end
+
+    private
+
+      def warn(method_name)
+        source = CallerFilter.first_non_rspec_line
+        Kernel.warn("An expectation of :#{method_name} was set on nil. Called from #{source}. Use allow_message_expectations_on_nil to disable warnings.")
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/space.rb b/rspec-mocks/lib/rspec/mocks/space.rb
new file mode 100644
index 0000000..2ed35eb
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/space.rb
@@ -0,0 +1,221 @@
+module RSpec
+  module Mocks
+    # @private
+    # Provides a default space implementation for outside
+    # the scope of an example. Called "root" because it serves
+    # as the root of the space stack.
+    class RootSpace
+      def proxy_for(*_args)
+        raise_lifecycle_message
+      end
+
+      def any_instance_recorder_for(*_args)
+        raise_lifecycle_message
+      end
+
+      def any_instance_proxy_for(*_args)
+        raise_lifecycle_message
+      end
+
+      def register_constant_mutator(_mutator)
+        raise_lifecycle_message
+      end
+
+      def any_instance_recorders_from_ancestry_of(_object)
+        raise_lifecycle_message
+      end
+
+      def reset_all
+      end
+
+      def verify_all
+      end
+
+      def registered?(_object)
+        false
+      end
+
+      def new_scope
+        Space.new
+      end
+
+    private
+
+      def raise_lifecycle_message
+        raise OutsideOfExampleError,
+              "The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported."
+      end
+    end
+
+    # @private
+    class Space
+      attr_reader :proxies, :any_instance_recorders, :proxy_mutex, :any_instance_mutex
+
+      def initialize
+        @proxies                 = {}
+        @any_instance_recorders  = {}
+        @constant_mutators       = []
+        @expectation_ordering    = OrderGroup.new
+        @proxy_mutex             = new_mutex
+        @any_instance_mutex      = new_mutex
+      end
+
+      def new_scope
+        NestedSpace.new(self)
+      end
+
+      def verify_all
+        proxies.values.each { |proxy| proxy.verify }
+        any_instance_recorders.each_value { |recorder| recorder.verify }
+      end
+
+      def reset_all
+        proxies.each_value { |proxy| proxy.reset }
+        @constant_mutators.reverse.each { |mut| mut.idempotently_reset }
+        any_instance_recorders.each_value { |recorder| recorder.stop_all_observation! }
+        any_instance_recorders.clear
+      end
+
+      def register_constant_mutator(mutator)
+        @constant_mutators << mutator
+      end
+
+      def constant_mutator_for(name)
+        @constant_mutators.find { |m| m.full_constant_name == name }
+      end
+
+      def any_instance_recorder_for(klass, only_return_existing=false)
+        any_instance_mutex.synchronize do
+          id = klass.__id__
+          any_instance_recorders.fetch(id) do
+            return nil if only_return_existing
+            any_instance_recorder_not_found_for(id, klass)
+          end
+        end
+      end
+
+      def any_instance_proxy_for(klass)
+        AnyInstance::Proxy.new(any_instance_recorder_for(klass), proxies_of(klass))
+      end
+
+      def proxies_of(klass)
+        proxies.values.select { |proxy| klass === proxy.object }
+      end
+
+      def proxy_for(object)
+        proxy_mutex.synchronize do
+          id = id_for(object)
+          proxies.fetch(id) { proxy_not_found_for(id, object) }
+        end
+      end
+
+      alias ensure_registered proxy_for
+
+      def registered?(object)
+        proxies.key?(id_for object)
+      end
+
+      def any_instance_recorders_from_ancestry_of(object)
+        # Optimization: `any_instance` is a feature we generally
+        # recommend not using, so we can often early exit here
+        # without doing an O(N) linear search over the number of
+        # ancestors in the object's class hierarchy.
+        return [] if any_instance_recorders.empty?
+
+        # We access the ancestors through the singleton class, to avoid calling
+        # `class` in case `class` has been stubbed.
+        (class << object; ancestors; end).map do |klass|
+          any_instance_recorders[klass.__id__]
+        end.compact
+      end
+
+    private
+
+      # We don't want to depend on the stdlib ourselves, but if the user is
+      # using threads then a Mutex will be available to us. If not, we don't
+      # need to synchronize anyway.
+      def new_mutex
+        defined?(::Mutex) ? ::Mutex.new : FakeMutex
+      end
+
+      # @private
+      module FakeMutex
+        def self.synchronize
+          yield
+        end
+      end
+
+      def proxy_not_found_for(id, object)
+        proxies[id] = case object
+                      when NilClass   then ProxyForNil.new(@expectation_ordering)
+                      when TestDouble then object.__build_mock_proxy_unless_expired(@expectation_ordering)
+                      when Class
+                        if RSpec::Mocks.configuration.verify_partial_doubles?
+                          VerifyingPartialClassDoubleProxy.new(self, object, @expectation_ordering)
+                        else
+                          PartialClassDoubleProxy.new(self, object, @expectation_ordering)
+                        end
+                      else
+                        if RSpec::Mocks.configuration.verify_partial_doubles?
+                          VerifyingPartialDoubleProxy.new(object, @expectation_ordering)
+                        else
+                          PartialDoubleProxy.new(object, @expectation_ordering)
+                        end
+                      end
+      end
+
+      def any_instance_recorder_not_found_for(id, klass)
+        any_instance_recorders[id] = AnyInstance::Recorder.new(klass)
+      end
+
+      if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2
+        require 'securerandom'
+
+        def id_for(object)
+          id = object.__id__
+
+          return id if object.equal?(::ObjectSpace._id2ref(id))
+          # this suggests that object.__id__ is proxying through to some wrapped object
+
+          object.instance_exec do
+            @__id_for_rspec_mocks_space ||= ::SecureRandom.uuid
+          end
+        end
+      else
+        def id_for(object)
+          object.__id__
+        end
+      end
+    end
+
+    # @private
+    class NestedSpace < Space
+      def initialize(parent)
+        @parent = parent
+        super()
+      end
+
+      def proxies_of(klass)
+        super + @parent.proxies_of(klass)
+      end
+
+      def constant_mutator_for(name)
+        super || @parent.constant_mutator_for(name)
+      end
+
+      def registered?(object)
+        super || @parent.registered?(object)
+      end
+
+    private
+
+      def proxy_not_found_for(id, object)
+        @parent.proxies[id] || super
+      end
+
+      def any_instance_recorder_not_found_for(id, klass)
+        @parent.any_instance_recorders[id] || super
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/standalone.rb b/rspec-mocks/lib/rspec/mocks/standalone.rb
new file mode 100644
index 0000000..74317b0
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/standalone.rb
@@ -0,0 +1,3 @@
+require 'rspec/mocks'
+extend RSpec::Mocks::ExampleMethods
+RSpec::Mocks.setup
diff --git a/rspec-mocks/lib/rspec/mocks/syntax.rb b/rspec-mocks/lib/rspec/mocks/syntax.rb
new file mode 100644
index 0000000..1ba4dcd
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/syntax.rb
@@ -0,0 +1,325 @@
+module RSpec
+  module Mocks
+    # @api private
+    # Provides methods for enabling and disabling the available syntaxes
+    # provided by rspec-mocks.
+    module Syntax
+      # @private
+      def self.warn_about_should!
+        @warn_about_should = true
+      end
+
+      # @private
+      def self.warn_unless_should_configured(method_name , replacement="the new `:expect` syntax or explicitly enable `:should`")
+        if @warn_about_should
+          RSpec.deprecate(
+            "Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
+            :replacement => replacement
+          )
+
+          @warn_about_should = false
+        end
+      end
+
+      # @api private
+      # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
+      def self.enable_should(syntax_host=default_should_syntax_host)
+        @warn_about_should = false if syntax_host == default_should_syntax_host
+        return if should_enabled?(syntax_host)
+
+        syntax_host.class_exec do
+          def should_receive(message, opts={}, &block)
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            ::RSpec::Mocks.expect_message(self, message, opts, &block)
+          end
+
+          def should_not_receive(message, &block)
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            ::RSpec::Mocks.expect_message(self, message, {}, &block).never
+          end
+
+          def stub(message_or_hash, opts={}, &block)
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            if ::Hash === message_or_hash
+              message_or_hash.each { |message, value| stub(message).and_return value }
+            else
+              ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block)
+            end
+          end
+
+          def unstub(message)
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to_receive(...).and_call_original` or explicitly enable `:should`")
+            ::RSpec::Mocks.space.proxy_for(self).remove_stub(message)
+          end
+
+          def stub_chain(*chain, &blk)
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk)
+          end
+
+          def as_null_object
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            @_null_object = true
+            ::RSpec::Mocks.space.proxy_for(self).as_null_object
+          end
+
+          def null_object?
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            defined?(@_null_object)
+          end
+
+          def received_message?(message, *args, &block)
+            ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+            ::RSpec::Mocks.space.proxy_for(self).received_message?(message, *args, &block)
+          end
+
+          unless Class.respond_to? :any_instance
+            Class.class_exec do
+              def any_instance
+                ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
+                ::RSpec::Mocks.space.any_instance_proxy_for(self)
+              end
+            end
+          end
+        end
+      end
+
+      # @api private
+      # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
+      def self.disable_should(syntax_host=default_should_syntax_host)
+        return unless should_enabled?(syntax_host)
+
+        syntax_host.class_exec do
+          undef should_receive
+          undef should_not_receive
+          undef stub
+          undef unstub
+          undef stub_chain
+          undef as_null_object
+          undef null_object?
+          undef received_message?
+        end
+
+        Class.class_exec do
+          undef any_instance
+        end
+      end
+
+      # @api private
+      # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
+      def self.enable_expect(syntax_host=::RSpec::Mocks::ExampleMethods)
+        return if expect_enabled?(syntax_host)
+
+        syntax_host.class_exec do
+          def receive(method_name, &block)
+            Matchers::Receive.new(method_name, block)
+          end
+
+          def receive_messages(message_return_value_hash)
+            matcher = Matchers::ReceiveMessages.new(message_return_value_hash)
+            matcher.warn_about_block if block_given?
+            matcher
+          end
+
+          def receive_message_chain(*messages, &block)
+            Matchers::ReceiveMessageChain.new(messages, &block)
+          end
+
+          def allow(target)
+            AllowanceTarget.new(target)
+          end
+
+          def expect_any_instance_of(klass)
+            AnyInstanceExpectationTarget.new(klass)
+          end
+
+          def allow_any_instance_of(klass)
+            AnyInstanceAllowanceTarget.new(klass)
+          end
+        end
+
+        RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do
+          def expect(target)
+            ExpectationTarget.new(target)
+          end
+        end
+      end
+
+      # @api private
+      # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
+      def self.disable_expect(syntax_host=::RSpec::Mocks::ExampleMethods)
+        return unless expect_enabled?(syntax_host)
+
+        syntax_host.class_exec do
+          undef receive
+          undef receive_messages
+          undef receive_message_chain
+          undef allow
+          undef expect_any_instance_of
+          undef allow_any_instance_of
+        end
+
+        RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do
+          undef expect
+        end
+      end
+
+      # @api private
+      # Indicates whether or not the should syntax is enabled.
+      def self.should_enabled?(syntax_host=default_should_syntax_host)
+        syntax_host.method_defined?(:should_receive)
+      end
+
+      # @api private
+      # Indicates whether or not the expect syntax is enabled.
+      def self.expect_enabled?(syntax_host=::RSpec::Mocks::ExampleMethods)
+        syntax_host.method_defined?(:allow)
+      end
+
+      # @api private
+      # Determines where the methods like `should_receive`, and `stub` are added.
+      def self.default_should_syntax_host
+        # JRuby 1.7.4 introduces a regression whereby `defined?(::BasicObject) => nil`
+        # yet `BasicObject` still exists and patching onto ::Object breaks things
+        # e.g. SimpleDelegator expectations won't work
+        #
+        # See: https://github.com/jruby/jruby/issues/814
+        if defined?(JRUBY_VERSION) && JRUBY_VERSION == '1.7.4' && RUBY_VERSION.to_f > 1.8
+          return ::BasicObject
+        end
+
+        # On 1.8.7, Object.ancestors.last == Kernel but
+        # things blow up if we include `RSpec::Mocks::Methods`
+        # into Kernel...not sure why.
+        return Object unless defined?(::BasicObject)
+
+        # MacRuby has BasicObject but it's not the root class.
+        return Object unless Object.ancestors.last == ::BasicObject
+
+        ::BasicObject
+      end
+    end
+  end
+end
+
+if defined?(BasicObject)
+  # The legacy `:should` syntax adds the following methods directly to
+  # `BasicObject` so that they are available off of any object. Note, however,
+  # that this syntax does not always play nice with delegate/proxy objects.
+  # We recommend you use the non-monkeypatching `:expect` syntax instead.
+  # @see Class
+  class BasicObject
+    # @method should_receive
+    # Sets an expectation that this object should receive a message before
+    # the end of the example.
+    #
+    # @example
+    #   logger = double('logger')
+    #   thing_that_logs = ThingThatLogs.new(logger)
+    #   logger.should_receive(:log)
+    #   thing_that_logs.do_something_that_logs_a_message
+    #
+    # @note This is only available when you have enabled the `should` syntax.
+    # @see RSpec::Mocks::ExampleMethods#expect
+
+    # @method should_not_receive
+    # Sets and expectation that this object should _not_ receive a message
+    # during this example.
+    # @see RSpec::Mocks::ExampleMethods#expect
+
+    # @method stub
+    # Tells the object to respond to the message with the specified value.
+    #
+    # @example
+    #   counter.stub(:count).and_return(37)
+    #   counter.stub(:count => 37)
+    #   counter.stub(:count) { 37 }
+    #
+    # @note This is only available when you have enabled the `should` syntax.
+    # @see RSpec::Mocks::ExampleMethods#allow
+
+    # @method unstub
+    # Removes a stub. On a double, the object will no longer respond to
+    # `message`. On a real object, the original method (if it exists) is
+    # restored.
+    #
+    # This is rarely used, but can be useful when a stub is set up during a
+    # shared `before` hook for the common case, but you want to replace it
+    # for a special case.
+    #
+    # @note This is only available when you have enabled the `should` syntax.
+
+    # @method stub_chain
+    # @overload stub_chain(method1, method2)
+    # @overload stub_chain("method1.method2")
+    # @overload stub_chain(method1, method_to_value_hash)
+    #
+    # Stubs a chain of methods.
+    #
+    # ## Warning:
+    #
+    # Chains can be arbitrarily long, which makes it quite painless to
+    # violate the Law of Demeter in violent ways, so you should consider any
+    # use of `stub_chain` a code smell. Even though not all code smells
+    # indicate real problems (think fluent interfaces), `stub_chain` still
+    # results in brittle examples.  For example, if you write
+    # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the
+    # implementation calls `foo.baz.bar`, the stub will not work.
+    #
+    # @example
+    #   double.stub_chain("foo.bar") { :baz }
+    #   double.stub_chain(:foo, :bar => :baz)
+    #   double.stub_chain(:foo, :bar) { :baz }
+    #
+    #     # Given any of ^^ these three forms ^^:
+    #     double.foo.bar # => :baz
+    #
+    #     # Common use in Rails/ActiveRecord:
+    #     Article.stub_chain("recent.published") { [Article.new] }
+    #
+    # @note This is only available when you have enabled the `should` syntax.
+    # @see RSpec::Mocks::ExampleMethods#receive_message_chain
+
+    # @method as_null_object
+    # Tells the object to respond to all messages. If specific stub values
+    # are declared, they'll work as expected. If not, the receiver is
+    # returned.
+    #
+    # @note This is only available when you have enabled the `should` syntax.
+
+    # @method null_object?
+    # Returns true if this object has received `as_null_object`
+    #
+    # @note This is only available when you have enabled the `should` syntax.
+  end
+end
+
+# The legacy `:should` syntax adds the `any_instance` to `Class`.
+# We generally recommend you use the newer `:expect` syntax instead,
+# which allows you to stub any instance of a class using
+# `allow_any_instance_of(klass)` or mock any instance using
+# `expect_any_instance_of(klass)`.
+# @see BasicObject
+class Class
+  # @method any_instance
+  # Used to set stubs and message expectations on any instance of a given
+  # class. Returns a [Recorder](Recorder), which records messages like
+  # `stub` and `should_receive` for later playback on instances of the
+  # class.
+  #
+  # @example
+  #   Car.any_instance.should_receive(:go)
+  #   race = Race.new
+  #   race.cars << Car.new
+  #   race.go # assuming this delegates to all of its cars
+  #           # this example would pass
+  #
+  #   Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
+  #   Account.new.balance # => Money.new(:USD, 25))
+  #
+  # @return [Recorder]
+  #
+  # @note This is only available when you have enabled the `should` syntax.
+  # @see RSpec::Mocks::ExampleMethods#expect_any_instance_of
+  # @see RSpec::Mocks::ExampleMethods#allow_any_instance_of
+end
diff --git a/rspec-mocks/lib/rspec/mocks/targets.rb b/rspec-mocks/lib/rspec/mocks/targets.rb
new file mode 100644
index 0000000..43436cc
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/targets.rb
@@ -0,0 +1,97 @@
+module RSpec
+  module Mocks
+    # @private
+    class TargetBase
+      def initialize(target)
+        @target = target
+      end
+
+      def self.delegate_to(matcher_method)
+        define_method(:to) do |matcher, &block|
+          unless matcher_allowed?(matcher)
+            raise_unsupported_matcher(:to, matcher)
+          end
+          define_matcher(matcher, matcher_method, &block)
+        end
+      end
+
+      def self.delegate_not_to(matcher_method, options={})
+        method_name = options.fetch(:from)
+        define_method(method_name) do |matcher, &block|
+          case matcher
+          when Matchers::Receive
+            define_matcher(matcher, matcher_method, &block)
+          when Matchers::ReceiveMessages, Matchers::ReceiveMessageChain
+            raise_negation_unsupported(method_name, matcher)
+          else
+            raise_unsupported_matcher(method_name, matcher)
+          end
+        end
+      end
+
+      def self.disallow_negation(method_name)
+        define_method(method_name) do |matcher, *_args|
+          raise_negation_unsupported(method_name, matcher)
+        end
+      end
+
+    private
+
+      def matcher_allowed?(matcher)
+        matcher.class.name.start_with?("RSpec::Mocks::Matchers".freeze)
+      end
+
+      def define_matcher(matcher, name, &block)
+        matcher.__send__(name, @target, &block)
+      end
+
+      def raise_unsupported_matcher(method_name, matcher)
+        raise UnsupportedMatcherError,
+              "only the `receive` or `receive_messages` matchers are supported " \
+              "with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}"
+      end
+
+      def raise_negation_unsupported(method_name, matcher)
+        raise NegationUnsupportedError,
+              "`#{expression}(...).#{method_name} #{matcher.name}` is not supported since it " \
+              "doesn't really make sense. What would it even mean?"
+      end
+
+      def expression
+        self.class::EXPRESSION
+      end
+    end
+
+    # @private
+    class AllowanceTarget < TargetBase
+      EXPRESSION = :allow
+      delegate_to :setup_allowance
+      disallow_negation :not_to
+      disallow_negation :to_not
+    end
+
+    # @private
+    class ExpectationTarget < TargetBase
+      EXPRESSION = :expect
+      delegate_to :setup_expectation
+      delegate_not_to :setup_negative_expectation, :from => :not_to
+      delegate_not_to :setup_negative_expectation, :from => :to_not
+    end
+
+    # @private
+    class AnyInstanceAllowanceTarget < TargetBase
+      EXPRESSION = :allow_any_instance_of
+      delegate_to :setup_any_instance_allowance
+      disallow_negation :not_to
+      disallow_negation :to_not
+    end
+
+    # @private
+    class AnyInstanceExpectationTarget < TargetBase
+      EXPRESSION = :expect_any_instance_of
+      delegate_to :setup_any_instance_expectation
+      delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to
+      delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/test_double.rb b/rspec-mocks/lib/rspec/mocks/test_double.rb
new file mode 100644
index 0000000..3b2056d
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/test_double.rb
@@ -0,0 +1,135 @@
+module RSpec
+  module Mocks
+    # Implements the methods needed for a pure test double.  RSpec::Mocks::Double
+    # includes this module, and it is provided for cases where you want a
+    # pure test double without subclassing RSpec::Mocks::Double.
+    module TestDouble
+      # Creates a new test double with a `name` (that will be used in error
+      # messages only)
+      def initialize(name=nil, stubs={})
+        @__expired = false
+        if Hash === name && stubs.empty?
+          stubs = name
+          @name = nil
+        else
+          @name = name
+        end
+        assign_stubs(stubs)
+      end
+
+      # Tells the object to respond to all messages. If specific stub values
+      # are declared, they'll work as expected. If not, the receiver is
+      # returned.
+      def as_null_object
+        __mock_proxy.as_null_object
+      end
+
+      # Returns true if this object has received `as_null_object`
+      def null_object?
+        __mock_proxy.null_object?
+      end
+
+      # This allows for comparing the mock to other objects that proxy such as
+      # ActiveRecords belongs_to proxy objects. By making the other object run
+      # the comparison, we're sure the call gets delegated to the proxy
+      # target.
+      def ==(other)
+        other == __mock_proxy
+      end
+
+      # @private
+      def inspect
+        "#<#{self.class}:#{'0x%x' % object_id} @name=#{@name.inspect}>"
+      end
+
+      # @private
+      def to_s
+        inspect.gsub('<', '[').gsub('>', ']')
+      end
+
+      # @private
+      def respond_to?(message, incl_private=false)
+        __mock_proxy.null_object? ? true : super
+      end
+
+      # @private
+      def __build_mock_proxy_unless_expired(order_group)
+        __raise_expired_error || __build_mock_proxy(order_group)
+      end
+
+      # @private
+      def __disallow_further_usage!
+        @__expired = true
+      end
+
+      # Override for default freeze implementation to prevent freezing of test
+      # doubles.
+      def freeze
+        RSpec.warn_with("WARNING: you attempted to freeze a test double. This is explicitly a no-op as freezing doubles can lead to undesired behaviour when resetting tests.")
+      end
+
+    private
+
+      def method_missing(message, *args, &block)
+        proxy = __mock_proxy
+        proxy.record_message_received(message, *args, &block)
+
+        if proxy.null_object?
+          case message
+          when :to_int        then return 0
+          when :to_a, :to_ary then return nil
+          when :to_str        then return to_s
+          else return self
+          end
+        end
+
+        # Defined private and protected methods will still trigger `method_missing`
+        # when called publicly. We want ruby's method visibility error to get raised,
+        # so we simply delegate to `super` in that case.
+        # ...well, we would delegate to `super`, but there's a JRuby
+        # bug, so we raise our own visibility error instead:
+        # https://github.com/jruby/jruby/issues/1398
+        visibility = proxy.visibility_for(message)
+        if visibility == :private || visibility == :protected
+          ErrorGenerator.new(self, @name).raise_non_public_error(
+            message, visibility
+          )
+        end
+
+        # Required wrapping doubles in an Array on Ruby 1.9.2
+        raise NoMethodError if [:to_a, :to_ary].include? message
+        proxy.raise_unexpected_message_error(message, *args)
+      end
+
+      def assign_stubs(stubs)
+        stubs.each_pair do |message, response|
+          __mock_proxy.add_simple_stub(message, response)
+        end
+      end
+
+      def __mock_proxy
+        ::RSpec::Mocks.space.proxy_for(self)
+      end
+
+      def __build_mock_proxy(order_group)
+        TestDoubleProxy.new(self, order_group, @name)
+      end
+
+      def __raise_expired_error
+        return false unless @__expired
+        ErrorGenerator.new(self, @name).raise_expired_test_double_error
+      end
+
+      def initialize_copy(other)
+        as_null_object if other.null_object?
+        super
+      end
+    end
+
+    # A generic test double object. `double`, `instance_double` and friends
+    # return an instance of this.
+    class Double
+      include TestDouble
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/verifying_double.rb b/rspec-mocks/lib/rspec/mocks/verifying_double.rb
new file mode 100644
index 0000000..afd12d9
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/verifying_double.rb
@@ -0,0 +1,134 @@
+RSpec::Support.require_rspec_mocks 'verifying_proxy'
+require 'stringio'
+
+module RSpec
+  module Mocks
+    # @private
+    module VerifyingDouble
+      def respond_to?(message, include_private=false)
+        return super unless null_object?
+
+        method_ref = __mock_proxy.method_reference[message]
+
+        case method_ref.visibility
+        when :public    then true
+        when :private   then include_private
+        when :protected then include_private || RUBY_VERSION.to_f < 2.0
+        else !method_ref.unimplemented?
+        end
+      end
+
+      def method_missing(message, *args, &block)
+        # Null object conditional is an optimization. If not a null object,
+        # validity of method expectations will have been checked at definition
+        # time.
+        if null_object?
+          if @__sending_message == message
+            __mock_proxy.ensure_implemented(message)
+          else
+            __mock_proxy.ensure_publicly_implemented(message, self)
+          end
+
+          __mock_proxy.validate_arguments!(message, args)
+        end
+
+        super
+      end
+
+      # Redefining `__send__` causes ruby to issue a warning.
+      old, $stderr = $stderr, StringIO.new
+      def __send__(name, *args, &block)
+        @__sending_message = name
+        super
+      ensure
+        @__sending_message = nil
+      end
+      $stderr = old
+
+      def send(name, *args, &block)
+        __send__(name, *args, &block)
+      end
+
+      def initialize(doubled_module, *args)
+        @doubled_module = doubled_module
+
+        possible_name = args.first
+        name = if String === possible_name || Symbol === possible_name
+                 args.shift
+               else
+                 @description
+               end
+
+        super(name, *args)
+        @__sending_message = nil
+      end
+    end
+
+    # A mock providing a custom proxy that can verify the validity of any
+    # method stubs or expectations against the public instance methods of the
+    # given class.
+    #
+    # @private
+    class InstanceVerifyingDouble
+      include TestDouble
+      include VerifyingDouble
+
+      def initialize(doubled_module, *args)
+        @description = "#{doubled_module.description} (instance)"
+        super
+      end
+
+      def __build_mock_proxy(order_group)
+        VerifyingProxy.new(self, order_group, @name,
+                           @doubled_module,
+                           InstanceMethodReference
+        )
+      end
+    end
+
+    # An awkward module necessary because we cannot otherwise have
+    # ClassVerifyingDouble inherit from Module and still share these methods.
+    #
+    # @private
+    module ObjectVerifyingDoubleMethods
+      include TestDouble
+      include VerifyingDouble
+
+      def as_stubbed_const(options={})
+        ConstantMutator.stub(@doubled_module.const_to_replace, self, options)
+        self
+      end
+
+    private
+
+      def initialize(doubled_module, *args)
+        @description = doubled_module.description
+        super
+      end
+
+      def __build_mock_proxy(order_group)
+        VerifyingProxy.new(self, order_group, @name,
+                           @doubled_module,
+                           ObjectMethodReference
+        )
+      end
+    end
+
+    # Similar to an InstanceVerifyingDouble, except that it verifies against
+    # public methods of the given object.
+    #
+    # @private
+    class ObjectVerifyingDouble
+      include ObjectVerifyingDoubleMethods
+    end
+
+    # Effectively the same as an ObjectVerifyingDouble (since a class is a type
+    # of object), except with Module in the inheritance chain so that
+    # transferring nested constants to work.
+    #
+    # @private
+    class ClassVerifyingDouble < Module
+      include ObjectVerifyingDoubleMethods
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/verifying_message_expecation.rb b/rspec-mocks/lib/rspec/mocks/verifying_message_expecation.rb
new file mode 100644
index 0000000..c81ef32
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/verifying_message_expecation.rb
@@ -0,0 +1,54 @@
+RSpec::Support.require_rspec_support 'method_signature_verifier'
+
+module RSpec
+  module Mocks
+    # A message expectation that knows about the real implementation of the
+    # message being expected, so that it can verify that any expectations
+    # have the valid arguments.
+    # @api private
+    class VerifyingMessageExpectation < MessageExpectation
+      # A level of indirection is used here rather than just passing in the
+      # method itself, since method look up is expensive and we only want to
+      # do it if actually needed.
+      #
+      # Conceptually the method reference makes more sense as a constructor
+      # argument since it should be immutable, but it is significantly more
+      # straight forward to build the object in pieces so for now it stays as
+      # an accessor.
+      attr_accessor :method_reference
+
+      def initialize(*args)
+        super
+      end
+
+      # @private
+      def with(*args, &block)
+        super(*args, &block).tap do
+          validate_expected_arguments! do |signature|
+            example_call_site_args = [:an_arg] * signature.min_non_kw_args
+            example_call_site_args << :kw_args_hash if signature.required_kw_args.any?
+            @argument_list_matcher.resolve_expected_args_based_on(example_call_site_args)
+          end
+        end
+      end
+
+    private
+
+      def validate_expected_arguments!
+        return if method_reference.nil?
+
+        method_reference.with_signature do |signature|
+          args     = yield signature
+          verifier = Support::LooseSignatureVerifier.new(signature, args)
+
+          unless verifier.valid?
+            # Fail fast is required, otherwise the message expecation will fail
+            # as well ("expected method not called") and clobber this one.
+            @failed_fast = true
+            @error_generator.raise_invalid_arguments_error(verifier)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/verifying_proxy.rb b/rspec-mocks/lib/rspec/mocks/verifying_proxy.rb
new file mode 100644
index 0000000..84ed3c6
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/verifying_proxy.rb
@@ -0,0 +1,173 @@
+RSpec::Support.require_rspec_mocks 'verifying_message_expecation'
+RSpec::Support.require_rspec_mocks 'method_reference'
+
+module RSpec
+  module Mocks
+    # @private
+    module VerifyingProxyMethods
+      def add_stub(method_name, opts={}, &implementation)
+        ensure_implemented(method_name)
+        super
+      end
+
+      def add_simple_stub(method_name, *args)
+        ensure_implemented(method_name)
+        super
+      end
+
+      def add_message_expectation(method_name, opts={}, &block)
+        ensure_implemented(method_name)
+        super
+      end
+
+      def ensure_implemented(method_name)
+        return unless method_reference[method_name].unimplemented?
+
+        @error_generator.raise_unimplemented_error(
+          @doubled_module,
+          method_name
+        )
+      end
+
+      def ensure_publicly_implemented(method_name, _object)
+        ensure_implemented(method_name)
+        visibility = method_reference[method_name].visibility
+
+        return if visibility == :public
+        @error_generator.raise_non_public_error(method_name, visibility)
+      end
+    end
+
+    # A verifying proxy mostly acts like a normal proxy, except that it
+    # contains extra logic to try and determine the validity of any expectation
+    # set on it. This includes whether or not methods have been defined and the
+    # validatiy of arguments on method calls.
+    #
+    # In all other ways this behaves like a normal proxy. It only adds the
+    # verification behaviour to specific methods then delegates to the parent
+    # implementation.
+    #
+    # These checks are only activated if the doubled class has already been
+    # loaded, otherwise they are disabled. This allows for testing in
+    # isolation.
+    #
+    # @private
+    class VerifyingProxy < TestDoubleProxy
+      include VerifyingProxyMethods
+
+      def initialize(object, order_group, name, doubled_module, method_reference_class)
+        super(object, order_group, name)
+        @object                 = object
+        @doubled_module         = doubled_module
+        @method_reference_class = method_reference_class
+
+        # A custom method double is required to pass through a way to lookup
+        # methods to determine their parameters. This is only relevant if the doubled
+        # class is loaded.
+        @method_doubles = Hash.new do |h, k|
+          h[k] = VerifyingMethodDouble.new(@object, k, self, method_reference[k])
+        end
+      end
+
+      def method_reference
+        @method_reference ||= Hash.new do |h, k|
+          h[k] = @method_reference_class.new(@doubled_module, k)
+        end
+      end
+
+      def visibility_for(method_name)
+        method_reference[method_name].visibility
+      end
+
+      def validate_arguments!(method_name, args)
+        @method_doubles[method_name].validate_arguments!(args)
+      end
+    end
+
+    # @private
+    class VerifyingPartialDoubleProxy < PartialDoubleProxy
+      include VerifyingProxyMethods
+
+      def initialize(object, expectation_ordering)
+        super(object, expectation_ordering)
+        @doubled_module = DirectObjectReference.new(object)
+
+        # A custom method double is required to pass through a way to lookup
+        # methods to determine their parameters.
+        @method_doubles = Hash.new do |h, k|
+          h[k] = VerifyingExistingMethodDouble.new(object, k, self)
+        end
+      end
+
+      def method_reference
+        @method_doubles
+      end
+    end
+
+    # @private
+    class VerifyingPartialClassDoubleProxy < VerifyingPartialDoubleProxy
+      include PartialClassDoubleProxyMethods
+    end
+
+    # @private
+    class VerifyingMethodDouble < MethodDouble
+      def initialize(object, method_name, proxy, method_reference)
+        super(object, method_name, proxy)
+        @method_reference = method_reference
+      end
+
+      def message_expectation_class
+        VerifyingMessageExpectation
+      end
+
+      def add_expectation(*args, &block)
+        # explict params necessary for 1.8.7 see #626
+        super(*args, &block).tap { |x| x.method_reference = @method_reference }
+      end
+
+      def add_stub(*args, &block)
+        # explict params necessary for 1.8.7 see #626
+        super(*args, &block).tap { |x| x.method_reference = @method_reference }
+      end
+
+      def proxy_method_invoked(obj, *args, &block)
+        validate_arguments!(args)
+        super
+      end
+
+      def validate_arguments!(actual_args)
+        @method_reference.with_signature do |signature|
+          verifier = Support::StrictSignatureVerifier.new(signature, actual_args)
+          raise ArgumentError, verifier.error_message unless verifier.valid?
+        end
+      end
+    end
+
+    # A VerifyingMethodDouble fetches the method to verify against from the
+    # original object, using a MethodReference. This works for pure doubles,
+    # but when the original object is itself the one being modified we need to
+    # collapse the reference and the method double into a single object so that
+    # we can access the original pristine method definition.
+    #
+    # @private
+    class VerifyingExistingMethodDouble < VerifyingMethodDouble
+      def initialize(object, method_name, proxy)
+        super(object, method_name, proxy, self)
+
+        @valid_method = object.respond_to?(method_name, true)
+
+        # Trigger an eager find of the original method since if we find it any
+        # later we end up getting a stubbed method with incorrect arity.
+        save_original_method!
+      end
+
+      def with_signature
+        yield Support::MethodSignature.new(original_method)
+      end
+
+      def unimplemented?
+        !@valid_method
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/lib/rspec/mocks/version.rb b/rspec-mocks/lib/rspec/mocks/version.rb
new file mode 100644
index 0000000..da8bbe6
--- /dev/null
+++ b/rspec-mocks/lib/rspec/mocks/version.rb
@@ -0,0 +1,9 @@
+module RSpec
+  module Mocks
+    # Version information for RSpec mocks.
+    module Version
+      # Version of RSpec mocks currently in use in SemVer format.
+      STRING = '3.2.1'
+    end
+  end
+end
diff --git a/rspec-mocks/maintenance-branch b/rspec-mocks/maintenance-branch
new file mode 100644
index 0000000..ad4dc0e
--- /dev/null
+++ b/rspec-mocks/maintenance-branch
@@ -0,0 +1 @@
+3-2-maintenance
diff --git a/rspec-mocks/rspec-mocks.gemspec b/rspec-mocks/rspec-mocks.gemspec
new file mode 100644
index 0000000..237b090
--- /dev/null
+++ b/rspec-mocks/rspec-mocks.gemspec
@@ -0,0 +1,46 @@
+# -*- encoding: utf-8 -*-
+$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
+require "rspec/mocks/version"
+
+Gem::Specification.new do |s|
+  s.name        = "rspec-mocks"
+  s.version     = RSpec::Mocks::Version::STRING
+  s.platform    = Gem::Platform::RUBY
+  s.license     = "MIT"
+  s.authors     = ["Steven Baker", "David Chelimsky", "Myron Marston"]
+  s.email       = "rspec at googlegroups.com"
+  s.homepage    = "http://github.com/rspec/rspec-mocks"
+  s.summary     = "rspec-mocks-#{RSpec::Mocks::Version::STRING}"
+  s.description = "RSpec's 'test double' framework, with support for stubbing and mocking"
+
+  s.rubyforge_project  = "rspec"
+
+  s.files            = `git ls-files -- lib/*`.split("\n")
+  s.files           += %w[README.md License.txt Changelog.md .yardopts .document]
+  s.test_files       = []
+  s.rdoc_options     = ["--charset=UTF-8"]
+  s.require_path     = "lib"
+
+  s.required_ruby_version = '>= 1.8.7'
+
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  if File.exist?(private_key)
+    s.signing_key = private_key
+    s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
+  end
+
+  if RSpec::Mocks::Version::STRING =~ /[a-zA-Z]+/
+    # pin to exact version for rc's and betas
+    s.add_runtime_dependency "rspec-support", "= #{RSpec::Mocks::Version::STRING}"
+  else
+    # pin to major/minor ignoring patch
+    s.add_runtime_dependency "rspec-support", "~> #{RSpec::Mocks::Version::STRING.split('.')[0..1].concat(['0']).join('.')}"
+  end
+
+  s.add_runtime_dependency "diff-lcs", ">= 1.2.0", "< 2.0"
+
+  s.add_development_dependency 'rake',     '~> 10.0.0'
+  s.add_development_dependency 'cucumber', '~> 1.3.15'
+  s.add_development_dependency 'aruba',    '~> 0.5'
+  s.add_development_dependency 'minitest', '~> 5.2'
+end
diff --git a/rspec-mocks/script/clone_all_rspec_repos b/rspec-mocks/script/clone_all_rspec_repos
new file mode 100755
index 0000000..f83d2e9
--- /dev/null
+++ b/rspec-mocks/script/clone_all_rspec_repos
@@ -0,0 +1,24 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+if is_mri; then
+  pushd ..
+
+  clone_repo "rspec"
+  clone_repo "rspec-core"
+  clone_repo "rspec-expectations"
+  clone_repo "rspec-mocks"
+  clone_repo "rspec-rails"
+
+  if rspec_support_compatible; then
+    clone_repo "rspec-support"
+  fi
+
+  popd
+else
+  echo "Not cloning all repos since we are not on MRI and they are only needed for the MRI build"
+fi
diff --git a/rspec-mocks/script/functions.sh b/rspec-mocks/script/functions.sh
new file mode 100644
index 0000000..a96a5c7
--- /dev/null
+++ b/rspec-mocks/script/functions.sh
@@ -0,0 +1,129 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $SCRIPT_DIR/travis_functions.sh
+source $SCRIPT_DIR/predicate_functions.sh
+
+# idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
+export JRUBY_OPTS="${JRUBY_OPTS} -X-C" # disable JIT since these processes are so short lived
+SPECS_HAVE_RUN_FILE=specs.out
+MAINTENANCE_BRANCH=`cat maintenance-branch`
+
+function clone_repo {
+  if [ ! -d $1 ]; then # don't clone if the dir is already there
+    travis_retry eval "git clone git://github.com/rspec/$1 --depth 1 --branch $MAINTENANCE_BRANCH"
+  fi;
+}
+
+function run_specs_and_record_done {
+  local rspec_bin=bin/rspec
+
+  # rspec-core needs to run with a special script that loads simplecov first,
+  # so that it can instrument rspec-core's code before rspec-core has been loaded.
+  if [ -f script/rspec_with_simplecov ]; then
+    rspec_bin=script/rspec_with_simplecov
+  fi;
+
+  echo "${PWD}/bin/rspec"
+  $rspec_bin spec --backtrace --format progress --profile --format progress --out $SPECS_HAVE_RUN_FILE
+}
+
+function run_cukes {
+  if [ -d features ]; then
+    # force jRuby to use client mode JVM or a compilation mode thats as close as possible,
+    # idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
+    #
+    # Note that we delay setting this until we run the cukes because we've seen
+    # spec failures in our spec suite due to problems with this mode.
+    export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
+
+    echo "${PWD}/bin/cucumber"
+
+    if is_mri_192; then
+      # For some reason we get SystemStackError on 1.9.2 when using
+      # the bin/cucumber approach below. That approach is faster
+      # (as it avoids the bundler tax), so we use it on rubies where we can.
+      bundle exec cucumber --strict
+    else
+      # Prepare RUBYOPT for scenarios that are shelling out to ruby,
+      # and PATH for those that are using `rspec` or `rake`.
+      RUBYOPT="-I${PWD}/../bundle -rbundler/setup" \
+         PATH="${PWD}/bin:$PATH" \
+         bin/cucumber --strict
+    fi
+  fi
+}
+
+function run_specs_one_by_one {
+  echo "Running each spec file, one-by-one..."
+
+  for file in `find spec -iname '*_spec.rb'`; do
+    bin/rspec $file -b --format progress
+  done
+}
+
+function run_spec_suite_for {
+  if [ ! -f ../$1/$SPECS_HAVE_RUN_FILE ]; then # don't rerun specs that have already run
+    echo "Running specs for $1"
+    pushd ../$1
+    unset BUNDLE_GEMFILE
+    bundle_install_flags=`cat .travis.yml | grep bundler_args | tr -d '"' | grep -o " .*"`
+    travis_retry eval "bundle install $bundle_install_flags"
+    run_specs_and_record_done
+    popd
+  fi;
+}
+
+function check_documentation_coverage {
+  echo "bin/yard stats --list-undoc"
+
+  bin/yard stats --list-undoc | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      coverage ||= line[/([\d\.]+)% documented/, 1]
+      puts line
+    end
+
+    unless Float(coverage) == 100
+      puts \"\n\nMissing documentation coverage (currently at #{coverage}%)\"
+      exit(1)
+    end
+
+    if has_warnings
+      puts \"\n\nYARD emitted documentation warnings.\"
+      exit(1)
+    end
+  "
+
+  # Some warnings only show up when generating docs, so do that as well.
+  bin/yard doc --no-cache | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      has_errors   ||= line.start_with?('[error]:')
+      puts line
+    end
+
+    if has_warnings || has_errors
+      puts \"\n\nYARD emitted documentation warnings or errors.\"
+      exit(1)
+    end
+  "
+}
+
+function check_style_and_lint {
+  echo "bin/rubucop lib"
+  bin/rubocop lib
+}
+
+function run_all_spec_suites {
+  fold "one-by-one specs" run_specs_one_by_one
+  fold "rspec-core specs" run_spec_suite_for "rspec-core"
+  fold "rspec-expectations specs" run_spec_suite_for "rspec-expectations"
+  fold "rspec-mocks specs" run_spec_suite_for "rspec-mocks"
+  fold "rspec-rails specs" run_spec_suite_for "rspec-rails"
+
+  if rspec_support_compatible; then
+    fold "rspec-support specs" run_spec_suite_for "rspec-support"
+  fi
+}
diff --git a/rspec-mocks/script/ignores b/rspec-mocks/script/ignores
new file mode 100644
index 0000000..14157db
--- /dev/null
+++ b/rspec-mocks/script/ignores
@@ -0,0 +1,55 @@
+# grep -v -f <this file> doesn't work properly when empty, so this line is here.
+
+# The `alias_method` calls below are only executed at file load time
+# (when the method cache will be busted by defining methods anyway).
+lib/rspec/mocks/argument_matchers.rb:      alias_method :hash_not_including, :hash_excluding
+lib/rspec/mocks/argument_matchers.rb:      alias_method :an_instance_of, :instance_of
+lib/rspec/mocks/argument_matchers.rb:      alias_method :a_kind_of, :kind_of
+lib/rspec/mocks/method_double.rb:      alias_method :save_original_method!, :original_method
+lib/rspec/mocks/test_double.rb:      alias_method :to_str, :to_s
+lib/rspec/mocks/error_generator.rb:    MockExpectationError = Class.new(Exception)
+lib/rspec/mocks/error_generator.rb:    ExpiredTestDoubleError = Class.new(MockExpectationError)
+lib/rspec/mocks/error_generator.rb:    OutsideOfExampleError = Class.new(StandardError)
+lib/rspec/mocks/error_generator.rb:    UnsupportedMatcherError  = Class.new(StandardError)
+lib/rspec/mocks/error_generator.rb:    NegationUnsupportedError = Class.new(StandardError)
+lib/rspec/mocks/message_expectation.rb:      CannotModifyFurtherError = Class.new(StandardError)
+lib/rspec/mocks/mutate_const.rb:      extend RecursiveConstMethods
+lib/rspec/mocks/mutate_const.rb:      extend RecursiveConstMethods
+
+# These calls are explicitly opt-in, probably at configuration time.
+lib/rspec/mocks/marshal_extension.rb:            alias_method :dump_without_rspec_mocks, :dump
+lib/rspec/mocks/marshal_extension.rb:            alias_method :dump, :dump_with_rspec_mocks
+lib/rspec/mocks/marshal_extension.rb:            alias_method :dump, :dump_without_rspec_mocks
+
+# False positives due to naming
+lib/rspec/mocks/any_instance/recorder.rb:        def build_alias_method_name(method_name)
+lib/rspec/mocks/any_instance/recorder.rb:          if public_protected_or_private_method_defined?(build_alias_method_name(method_name))
+lib/rspec/mocks/any_instance/recorder.rb:            alias_method_name = build_alias_method_name(method_name)
+lib/rspec/mocks/any_instance/recorder.rb:          alias_method_name = build_alias_method_name(method_name)
+lib/rspec/mocks/proxy.rb:            build_alias_method_name(message)
+
+# Instance method stashing needs to blow away method cache, no way around it.
+lib/rspec/mocks/any_instance/recorder.rb:              alias_method  method_name, alias_method_name
+lib/rspec/mocks/any_instance/recorder.rb:            alias_method alias_method_name, method_name
+lib/rspec/mocks/any_instance/recorder.rb:              remove_method method_name
+lib/rspec/mocks/any_instance/recorder.rb:              remove_method alias_method_name
+lib/rspec/mocks/any_instance/recorder.rb:            remove_method method_name
+lib/rspec/mocks/instance_method_stasher.rb:          @klass.__send__(:alias_method, stashed_method_name, @method)
+lib/rspec/mocks/instance_method_stasher.rb:          @klass.__send__(:alias_method, @method, stashed_method_name)
+lib/rspec/mocks/instance_method_stasher.rb:          @klass.__send__(:remove_method, stashed_method_name)
+
+# Constant stubbing needs to blow away method cache, no way around it.
+lib/rspec/mocks/method_double.rb:        object_singleton_class.__send__(:remove_method, @method_name)
+lib/rspec/mocks/mutate_const.rb:          @context.const_set(@const_name, @original_value)
+lib/rspec/mocks/mutate_const.rb:          @context.const_set(@const_name, @mutated_value)
+lib/rspec/mocks/mutate_const.rb:          @context.const_set(@const_name, @original_value)
+lib/rspec/mocks/mutate_const.rb:            @mutated_value.const_set(const, get_const_defined_on(original_value, const))
+lib/rspec/mocks/mutate_const.rb:            klass.const_set(name, Module.new)
+lib/rspec/mocks/mutate_const.rb:          context.const_set(@const_name, @mutated_value)
+lib/rspec/mocks/mutate_const.rb:          @context.__send__(:remove_const, @const_name)
+lib/rspec/mocks/mutate_const.rb:          @context.__send__(:remove_const, @const_name)
+lib/rspec/mocks/mutate_const.rb:          @context.__send__(:remove_const, @const_name)
+lib/rspec/mocks/mutate_const.rb:          @deepest_defined_const.__send__(:remove_const, @const_to_remove)
+
+# We provide our own wrapper around extend for others to use if they choose.
+lib/rspec/mocks/test_double.rb:        object.extend self
diff --git a/rspec-mocks/script/list_method_cache_busters.sh b/rspec-mocks/script/list_method_cache_busters.sh
new file mode 100755
index 0000000..5eedd94
--- /dev/null
+++ b/rspec-mocks/script/list_method_cache_busters.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# set -x
+
+# This list is from https://charlie.bz/blog/things-that-clear-rubys-method-cache
+
+IGNORE_FILE=/tmp/cache_busters_ignore
+COMMENT_LINE_RE="^(\w|\/)+\.rb: +#"
+
+cat script/ignores | grep -v "^$" | ruby -ne 'puts $_.split(/\s+###/)[0]' > $IGNORE_FILE
+
+egrep 'def [a-z]*\..*' -R lib | grep -v "def self" | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+egrep 'undef\\b' -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep alias_method -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep remove_method -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep const_set -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep remove_const -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+egrep '\bextend\b' -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep 'Class.new' -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep private_constant -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep public_constant -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep "Marshal.load" -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
+grep "OpenStruct.new" -R lib | grep -v -f $IGNORE_FILE | egrep -v "$COMMENT_LINE_RE"
diff --git a/rspec-mocks/script/predicate_functions.sh b/rspec-mocks/script/predicate_functions.sh
new file mode 100644
index 0000000..fc5d372
--- /dev/null
+++ b/rspec-mocks/script/predicate_functions.sh
@@ -0,0 +1,64 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+function is_mri {
+  if ruby -e "exit(!defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby')"; then
+    # RUBY_ENGINE only returns 'ruby' on MRI.
+    # MRI 1.8.7 lacks the constant but all other rubies have it (including JRuby in 1.8 mode)
+    return 0
+  else
+    return 1
+  fi;
+}
+
+function is_mri_192 {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION == '1.9.2')"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function is_mri_2plus {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION.to_f > 2.0)"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function rspec_support_compatible {
+  if [ "$MAINTENANCE_BRANCH" != "2-99-maintenance" ] && [ "$MAINTENANCE_BRANCH" != "2-14-maintenance" ]; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+function documentation_enforced {
+  if [ -x ./bin/yard ]; then
+    if is_mri_2plus; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function style_and_lint_enforced {
+ if [ -x ./bin/rubocop ]; then
+   return 0
+ else
+   return 1
+ fi
+}
diff --git a/rspec-mocks/script/run_build b/rspec-mocks/script/run_build
new file mode 100755
index 0000000..e1edcef
--- /dev/null
+++ b/rspec-mocks/script/run_build
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+# Allow repos to override the default functions and add their own
+if [ -f script/custom_build_functions.sh ]; then
+  source script/custom_build_functions.sh
+fi
+
+fold "specs" run_specs_and_record_done
+fold "cukes" run_cukes
+
+if documentation_enforced; then
+  fold "doc check" check_documentation_coverage
+fi
+
+if style_and_lint_enforced; then
+  fold "rubocop" check_style_and_lint
+fi
+
+if is_mri; then
+  run_all_spec_suites
+else
+  echo "Skipping the rest of the build on non-MRI rubies"
+fi
diff --git a/rspec-mocks/script/travis_functions.sh b/rspec-mocks/script/travis_functions.sh
new file mode 100644
index 0000000..77829b3
--- /dev/null
+++ b/rspec-mocks/script/travis_functions.sh
@@ -0,0 +1,69 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# Taken from:
+# https://github.com/travis-ci/travis-build/blob/e9314616e182a23e6a280199cd9070bfc7cae548/lib/travis/build/script/templates/header.sh#L34-L53
+travis_retry() {
+  local result=0
+  local count=1
+  while [ $count -le 3 ]; do
+    [ $result -ne 0 ] && {
+      echo -e "\n\033[33;1mThe command \"$@\" failed. Retrying, $count of 3.\033[0m\n" >&2
+    }
+    "$@"
+    result=$?
+    [ $result -eq 0 ] && break
+    count=$(($count + 1))
+    sleep 1
+  done
+
+  [ $count -eq 3 ] && {
+    echo "\n\033[33;1mThe command \"$@\" failed 3 times.\033[0m\n" >&2
+  }
+
+  return $result
+}
+
+# Taken from https://github.com/vcr/vcr/commit/fa96819c92b783ec0c794f788183e170e4f684b2
+# and https://github.com/vcr/vcr/commit/040aaac5370c68cd13c847c076749cd547a6f9b1
+nano_cmd="$(type -p gdate date | head -1)"
+nano_format="+%s%N"
+[ "$(uname -s)" != "Darwin" ] || nano_format="${nano_format/%N/000000000}"
+
+travis_time_start() {
+  travis_timer_id=$(printf %08x $(( RANDOM * RANDOM )))
+  travis_start_time=$($nano_cmd -u "$nano_format")
+  printf "travis_time:start:%s\r\e[0m" $travis_timer_id
+}
+
+travis_time_finish() {
+  local travis_end_time=$($nano_cmd -u "$nano_format")
+  local duration=$(($travis_end_time-$travis_start_time))
+  printf "travis_time:end:%s:start=%s,finish=%s,duration=%s\r\e[0m" \
+    $travis_timer_id $travis_start_time $travis_end_time $duration
+}
+
+fold() {
+  local name="$1"
+  local status=0
+  shift 1
+  if [ -n "$TRAVIS" ]; then
+    printf "travis_fold:start:%s\r\e[0m" "$name"
+    travis_time_start
+  fi
+
+  "$@"
+  status=$?
+
+  [ -z "$TRAVIS" ] || travis_time_finish
+
+  if [ "$status" -eq 0 ]; then
+    if [ -n "$TRAVIS" ]; then
+      printf "travis_fold:end:%s\r\e[0m" "$name"
+    fi
+  else
+    STATUS="$status"
+  fi
+
+  return $status
+}
diff --git a/rspec-mocks/spec/rspec/mocks/and_call_original_spec.rb b/rspec-mocks/spec/rspec/mocks/and_call_original_spec.rb
new file mode 100644
index 0000000..fdc0b2a
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/and_call_original_spec.rb
@@ -0,0 +1,267 @@
+require 'delegate'
+
+RSpec.describe "and_call_original" do
+  context "on a partial double" do
+    let(:klass) do
+      Class.new do
+        def meth_1
+          :original
+        end
+
+        def meth_2(x)
+          yield x, :additional_yielded_arg
+        end
+
+        def self.new_instance
+          new
+        end
+      end
+    end
+
+    let(:instance) { klass.new }
+
+    context "when a method that exists has been stubbed previously" do
+      before { allow(instance).to receive(:meth_1).and_return(:override) }
+
+      it 'restores the original behavior' do
+        expect {
+          allow(instance).to receive(:meth_1).and_call_original
+        }.to change(instance, :meth_1).from(:override).to(:original)
+      end
+    end
+
+    context "when a non-existant method has been stubbed previously" do
+      it 'restores the original NameError behavior' do
+        expect { instance.abcd }.to raise_error(NameError).with_message(/abcd/)
+
+        allow(instance).to receive(:abcd).and_return(:override)
+        expect(instance.abcd).to eq(:override)
+
+        allow(instance).to receive(:abcd).and_call_original
+        expect { instance.abcd }.to raise_error(NameError).with_message(/abcd/)
+      end
+    end
+
+    it 'passes the received message through to the original method' do
+      expect(instance).to receive(:meth_1).and_call_original
+      expect(instance.meth_1).to eq(:original)
+    end
+
+    it 'ignores prior declared stubs' do
+      allow(instance).to receive(:meth_1).and_return(:stubbed_value)
+      expect(instance).to receive(:meth_1).and_call_original
+      expect(instance.meth_1).to eq(:original)
+    end
+
+    it 'passes args and blocks through to the original method' do
+      expect(instance).to receive(:meth_2).and_call_original
+      value = instance.meth_2(:submitted_arg) { |a, b| [a, b] }
+      expect(value).to eq([:submitted_arg, :additional_yielded_arg])
+    end
+
+    it 'errors when you pass through the wrong number of args' do
+      expect(instance).to receive(:meth_1).and_call_original
+      expect(instance).to receive(:meth_2).twice.and_call_original
+      expect { instance.meth_1 :a }.to raise_error ArgumentError
+      expect { instance.meth_2 {} }.to raise_error ArgumentError
+      expect { instance.meth_2(:a, :b) {}  }.to raise_error ArgumentError
+    end
+
+    it 'warns when you override an existing implementation' do
+      expect(RSpec).to receive(:warning).with(/overriding a previous stub implementation of `meth_1`.*#{__FILE__}:#{__LINE__ + 1}/)
+      expect(instance).to receive(:meth_1) { true }.and_call_original
+      instance.meth_1
+    end
+
+    context "for singleton methods" do
+      it 'works' do
+        def instance.foo; :bar; end
+        expect(instance).to receive(:foo).and_call_original
+        expect(instance.foo).to eq(:bar)
+      end
+
+      it 'works for SimpleDelegator subclasses', :if => (RUBY_VERSION.to_f > 1.8) do
+        inst = Class.new(SimpleDelegator).new(1)
+        def inst.foo; :bar; end
+        expect(inst).to receive(:foo).and_call_original
+        expect(inst.foo).to eq(:bar)
+      end
+    end
+
+    it 'works for methods added through an extended module' do
+      instance.extend Module.new { def foo; :bar; end }
+      expect(instance).to receive(:foo).and_call_original
+      expect(instance.foo).to eq(:bar)
+    end
+
+    it "works for method added through an extended module onto a class's ancestor" do
+      sub_sub_klass = Class.new(Class.new(klass))
+      klass.extend Module.new { def foo; :bar; end }
+      expect(sub_sub_klass).to receive(:foo).and_call_original
+      expect(sub_sub_klass.foo).to eq(:bar)
+    end
+
+    it "finds the method on the most direct ancestor even if the method " +
+       "is available on more distant ancestors" do
+      klass.extend Module.new { def foo; :klass_bar; end }
+      sub_klass = Class.new(klass)
+      sub_klass.extend Module.new { def foo; :sub_klass_bar; end }
+      expect(sub_klass).to receive(:foo).and_call_original
+      expect(sub_klass.foo).to eq(:sub_klass_bar)
+    end
+
+    it "finds the method on the most direct singleton class ancestors even if the method " +
+       "is available on more distant ancestors" do
+      klass.extend Module.new { def foo; :klass_bar; end }
+      sub_klass = Class.new(klass) { def self.foo; :sub_klass_bar; end }
+      sub_sub_klass = Class.new(sub_klass)
+      expect(sub_sub_klass).to receive(:foo).and_call_original
+      expect(sub_sub_klass.foo).to eq(:sub_klass_bar)
+    end
+
+    context 'when using any_instance' do
+      it 'works for instance methods defined on the class' do
+        expect_any_instance_of(klass).to receive(:meth_1).and_call_original
+        expect(klass.new.meth_1).to eq(:original)
+      end
+
+      it 'works for instance methods defined on the superclass of the class' do
+        subclass = Class.new(klass)
+        expect_any_instance_of(subclass).to receive(:meth_1).and_call_original
+        expect(subclass.new.meth_1).to eq(:original)
+      end
+
+      it 'works when mocking the method on one class and calling the method on an instance of a subclass' do
+        expect_any_instance_of(klass).to receive(:meth_1).and_call_original
+        expect(Class.new(klass).new.meth_1).to eq(:original)
+      end
+    end
+
+    it 'works for class methods defined on a superclass' do
+      subclass = Class.new(klass)
+      expect(subclass).to receive(:new_instance).and_call_original
+      expect(subclass.new_instance).to be_a(subclass)
+    end
+
+    it 'works for class methods defined on a grandparent class' do
+      sub_subclass = Class.new(Class.new(klass))
+      expect(sub_subclass).to receive(:new_instance).and_call_original
+      expect(sub_subclass.new_instance).to be_a(sub_subclass)
+    end
+
+    it 'works for class methods defined on the Class class' do
+      expect(klass).to receive(:new).and_call_original
+      expect(klass.new).to be_an_instance_of(klass)
+    end
+
+    it "works for instance methods defined on the object's class's superclass" do
+      subclass = Class.new(klass)
+      inst = subclass.new
+      expect(inst).to receive(:meth_1).and_call_original
+      expect(inst.meth_1).to eq(:original)
+    end
+
+    it 'works for aliased methods' do
+      klazz = Class.new do
+        class << self
+          alias alternate_new new
+        end
+      end
+
+      expect(klazz).to receive(:alternate_new).and_call_original
+      expect(klazz.alternate_new).to be_an_instance_of(klazz)
+    end
+
+    context 'on an object that defines method_missing' do
+      before do
+        klass.class_exec do
+          private
+
+          def method_missing(name, *args)
+            if name.to_s == "greet_jack"
+              "Hello, jack"
+            else
+              super
+            end
+          end
+        end
+      end
+
+      it 'works when the method_missing definition handles the message' do
+        expect(instance).to receive(:greet_jack).and_call_original
+        expect(instance.greet_jack).to eq("Hello, jack")
+      end
+
+      it 'works for an any_instance partial mock' do
+        expect_any_instance_of(klass).to receive(:greet_jack).and_call_original
+        expect(instance.greet_jack).to eq("Hello, jack")
+      end
+
+      it 'raises an error for an unhandled message for an any_instance partial mock' do
+        expect_any_instance_of(klass).to receive(:not_a_handled_message).and_call_original
+        expect {
+          instance.not_a_handled_message
+        }.to raise_error(NameError, /not_a_handled_message/)
+      end
+
+      it 'raises an error on invocation if method_missing does not handle the message' do
+        expect(instance).to receive(:not_a_handled_message).and_call_original
+
+        # Note: it should raise a NoMethodError (and usually does), but
+        # due to a weird rspec-expectations issue (see #183) it sometimes
+        # raises a `NameError` when a `be_xxx` predicate matcher has been
+        # recently used. `NameError` is the superclass of `NoMethodError`
+        # so this example will pass regardless.
+        # If/when we solve the rspec-expectations issue, this can (and should)
+        # be changed to `NoMethodError`.
+        expect {
+          instance.not_a_handled_message
+        }.to raise_error(NameError, /not_a_handled_message/)
+      end
+    end
+  end
+
+  context "on a partial double that overrides #method" do
+    let(:request_klass) do
+      Struct.new(:method, :url) do
+        def perform
+          :the_response
+        end
+
+        def self.method
+          :some_method
+        end
+      end
+    end
+
+    let(:request) { request_klass.new(:get, "http://foo.com/bar") }
+
+    it 'still works even though #method has been overriden' do
+      expect(request).to receive(:perform).and_call_original
+      expect(request.perform).to eq(:the_response)
+    end
+
+    it 'works for a singleton method' do
+      def request.perform
+        :a_response
+      end
+
+      expect(request).to receive(:perform).and_call_original
+      expect(request.perform).to eq(:a_response)
+    end
+  end
+
+  context "on a pure test double" do
+    let(:instance) { double }
+
+    it 'raises an error even if the double object responds to the message' do
+      expect(instance.to_s).to be_a(String)
+      mock_expectation = expect(instance).to receive(:to_s)
+      instance.to_s # to satisfy the expectation
+
+      expect {
+        mock_expectation.and_call_original
+      }.to raise_error(/pure test double.*and_call_original.*partial double/i)
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/and_return_spec.rb b/rspec-mocks/spec/rspec/mocks/and_return_spec.rb
new file mode 100644
index 0000000..a05c280
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/and_return_spec.rb
@@ -0,0 +1,21 @@
+module RSpec
+  module Mocks
+    RSpec.describe 'and_return' do
+      let(:obj) { double('obj') }
+
+      context 'when a block is passed' do
+        it 'raises ArgumentError' do
+          expect {
+            allow(obj).to receive(:foo).and_return('bar') { 'baz' }
+          }.to raise_error(ArgumentError, /implementation block/i)
+        end
+      end
+
+      context 'when no argument is passed' do
+        it 'raises ArgumentError' do
+          expect { allow(obj).to receive(:foo).and_return }.to raise_error(ArgumentError)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/and_wrap_original_spec.rb b/rspec-mocks/spec/rspec/mocks/and_wrap_original_spec.rb
new file mode 100644
index 0000000..cf6d96e
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/and_wrap_original_spec.rb
@@ -0,0 +1,77 @@
+RSpec.describe "and_wrap_original" do
+  context "on a partial double" do
+    let(:klass) do
+      Class.new do
+        def results
+          (1..100).to_a
+        end
+      end
+    end
+
+    let(:instance) { klass.new }
+
+    shared_examples "using and_wrap_original" do
+      it "allows us to modify the results of the original method" do
+        expect {
+          allow_it.to receive(:results).and_wrap_original do |m|
+            m.call.first(10)
+          end
+        }.to change { instance.results.size }.from(100).to(10)
+      end
+
+      it "raises a name error if the method does not exist" do
+        expect {
+          allow_it.to receive(:no_results).and_wrap_original { |m| m.call }
+          instance.no_results
+        }.to raise_error NameError
+      end
+
+      it "passes in the original method" do
+        value = nil
+        original_method = instance.method(:results)
+        allow_it.to receive(:results).and_wrap_original { |m| value = m }
+        instance.results
+        expect(value).to eq original_method
+      end
+
+      it "passes along the message arguments" do
+        values = nil
+        allow_it.to receive(:results).and_wrap_original { |_, *args| values  = args }
+        instance.results(1, 2, 3)
+        expect(values).to eq [1, 2, 3]
+      end
+
+      it "passes along any supplied block" do
+        value = nil
+        allow_it.to receive(:results).and_wrap_original { |&b| value = b }
+        instance.results(&(block = proc {}))
+        expect(value).to eq block
+      end
+
+      it "ignores previous stubs" do
+        allow_it.to receive(:results) { "results" }
+        allow_it.to receive(:results).and_wrap_original { |m| m.call }
+        expect(instance.results).to_not eq "results"
+      end
+
+      it "can be constrained by specific arguments" do
+        allow_it.to receive(:results) { :all }
+        allow_it.to receive(:results).with(5).and_wrap_original { |m, n| m.call.first(n) }
+        expect(instance.results 5).to eq [1,2,3,4,5]
+        expect(instance.results).to eq :all
+      end
+    end
+
+    describe "allow(...).to receive(...).and_wrap_original" do
+      it_behaves_like "using and_wrap_original" do
+        let(:allow_it) { allow(instance) }
+      end
+    end
+
+    describe "allow_any_instance_of(...).to receive(...).and_wrap_original" do
+      it_behaves_like "using and_wrap_original" do
+        let(:allow_it) { allow_any_instance_of(klass) }
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/and_yield_spec.rb b/rspec-mocks/spec/rspec/mocks/and_yield_spec.rb
new file mode 100644
index 0000000..ab97476
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/and_yield_spec.rb
@@ -0,0 +1,161 @@
+RSpec.describe RSpec::Mocks::Double do
+
+  let(:obj) { double }
+
+  describe "#and_yield" do
+    context 'when the method double has been constrained by `with`' do
+      it 'uses the default stub if the provided args do not match' do
+        allow(obj).to receive(:foo) { 15 }
+        allow(obj).to receive(:foo).with(:yield).and_yield
+
+        # should_receive is required to trigger the bug:
+        # https://github.com/rspec/rspec-mocks/issues/127
+        expect(obj).to receive(:foo)
+
+        expect(obj.foo(:dont_yield)).to eq(15)
+      end
+    end
+
+    context "with eval context as block argument" do
+
+      it "evaluates the supplied block as it is read" do
+        evaluated = false
+        allow(obj).to receive(:method_that_accepts_a_block).and_yield do |eval_context|
+          evaluated = true
+        end
+        expect(evaluated).to be_truthy
+      end
+
+      it "passes an eval context object to the supplied block" do
+        allow(obj).to receive(:method_that_accepts_a_block).and_yield do |eval_context|
+          expect(eval_context).not_to be_nil
+        end
+      end
+
+      it "evaluates the block passed to the stubbed method in the context of the supplied eval context" do
+        expected_eval_context = nil
+        actual_eval_context = nil
+
+        allow(obj).to receive(:method_that_accepts_a_block).and_yield do |eval_context|
+          expected_eval_context = eval_context
+        end
+
+        obj.method_that_accepts_a_block do
+          actual_eval_context = self
+        end
+
+        expect(actual_eval_context).to equal(expected_eval_context)
+      end
+
+      context "and no yielded arguments" do
+
+        it "passes when expectations set on the eval context are met" do
+          configured_eval_context = nil
+          allow(obj).to receive(:method_that_accepts_a_block).and_yield do |eval_context|
+            configured_eval_context = eval_context
+            expect(configured_eval_context).to receive(:foo)
+          end
+
+          obj.method_that_accepts_a_block do
+            foo
+          end
+
+          verify configured_eval_context
+        end
+
+        it "fails when expectations set on the eval context are not met" do
+          configured_eval_context = nil
+          allow(obj).to receive(:method_that_accepts_a_block).and_yield do |eval_context|
+            configured_eval_context = eval_context
+            expect(configured_eval_context).to receive(:foo)
+          end
+
+          obj.method_that_accepts_a_block do
+            # foo is not called here
+          end
+
+          expect { verify configured_eval_context }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+      end
+
+      context "and yielded arguments" do
+
+        it "passes when expectations set on the eval context and yielded arguments are met" do
+          configured_eval_context = nil
+          yielded_arg = Object.new
+          allow(obj).to receive(:method_that_accepts_a_block).and_yield(yielded_arg) do |eval_context|
+            configured_eval_context = eval_context
+            expect(configured_eval_context).to receive(:foo)
+            expect(yielded_arg).to receive(:bar)
+          end
+
+          obj.method_that_accepts_a_block do |object|
+            object.bar
+            foo
+          end
+
+          verify configured_eval_context
+          verify yielded_arg
+        end
+
+        context "that are optional", :if => RSpec::Support::RubyFeatures.optional_and_splat_args_supported? do
+          it "yields the default argument when the argument is not given" do
+            pending "Not sure how to achieve this yet. See rspec/rspec-mocks#714 and rspec/rspec-support#85."
+            default_arg = Object.new
+            object = Object.new
+
+            allow(object).to receive(:a_message).and_yield
+            expect(default_arg).to receive(:bar)
+
+            eval("object.a_message { |receiver=default_arg| receiver.bar }")
+          end
+
+          it "yields given argument when the argument is given" do
+            default_arg = Object.new
+            allow(default_arg).to receive(:bar)
+
+            given_arg = Object.new
+            object = Object.new
+
+            allow(object).to receive(:a_message).and_yield(given_arg)
+            expect(given_arg).to receive(:bar)
+
+            eval("object.a_message { |receiver=default_arg| receiver.bar }")
+          end
+        end
+
+        it 'can yield to a block that uses `super`' do
+          klass    = Class.new { def foo; 13; end }
+          subklass = Class.new(klass) { def foo(arg); arg.bar { super() }; end }
+
+          arg = double
+          expect(arg).to receive(:bar).and_yield
+
+          instance = subklass.new
+          instance.foo(arg)
+        end
+
+        it "fails when expectations set on the eval context and yielded arguments are not met" do
+          configured_eval_context = nil
+          yielded_arg = Object.new
+          allow(obj).to receive(:method_that_accepts_a_block).and_yield(yielded_arg) do |eval_context|
+            configured_eval_context = eval_context
+            expect(configured_eval_context).to receive(:foo)
+            expect(yielded_arg).to receive(:bar)
+          end
+
+          obj.method_that_accepts_a_block do |obj|
+            # obj.bar is not called here
+            # foo is not called here
+          end
+
+          expect { verify configured_eval_context }.to raise_error(RSpec::Mocks::MockExpectationError)
+          expect { verify yielded_arg }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/any_instance/message_chains_spec.rb b/rspec-mocks/spec/rspec/mocks/any_instance/message_chains_spec.rb
new file mode 100644
index 0000000..723205e
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/any_instance/message_chains_spec.rb
@@ -0,0 +1,39 @@
+RSpec.describe RSpec::Mocks::AnyInstance::MessageChains do
+  let(:recorder) { double }
+  let(:chains) { RSpec::Mocks::AnyInstance::MessageChains.new }
+  let(:stub_chain) { RSpec::Mocks::AnyInstance::StubChain.new recorder }
+  let(:expectation_chain) { RSpec::Mocks::AnyInstance::PositiveExpectationChain.new recorder }
+
+  it "knows if a method does not have an expectation set on it" do
+    chains.add(:method_name, stub_chain)
+    expect(chains.has_expectation?(:method_name)).to be_falsey
+  end
+
+  it "knows if a method has an expectation set on it" do
+    chains.add(:method_name, stub_chain)
+    chains.add(:method_name, expectation_chain)
+    expect(chains.has_expectation?(:method_name)).to be_truthy
+  end
+
+  it "can remove all stub chains" do
+    chains.add(:method_name, stub_chain)
+    chains.add(:method_name, expectation_chain)
+    chains.add(:method_name, RSpec::Mocks::AnyInstance::StubChain.new(recorder))
+
+    chains.remove_stub_chains_for!(:method_name)
+    expect(chains[:method_name]).to eq([expectation_chain])
+  end
+
+  context "creating stub chains" do
+    it "understands how to add a stub chain for a method" do
+      chains.add(:method_name, stub_chain)
+      expect(chains[:method_name]).to eq([stub_chain])
+    end
+
+    it "allows multiple stub chains for a method" do
+      chains.add(:method_name, stub_chain)
+      chains.add(:method_name, another_stub_chain = RSpec::Mocks::AnyInstance::StubChain.new(recorder))
+      expect(chains[:method_name]).to eq([stub_chain, another_stub_chain])
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/any_instance_spec.rb b/rspec-mocks/spec/rspec/mocks/any_instance_spec.rb
new file mode 100644
index 0000000..6555e61
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/any_instance_spec.rb
@@ -0,0 +1,1242 @@
+require 'delegate'
+
+module RSpec
+  module Mocks
+    RSpec.describe "#any_instance" do
+      class CustomErrorForAnyInstanceSpec < StandardError;end
+
+      let(:klass) do
+        Class.new do
+          def existing_method; :existing_method_return_value; end
+          def existing_method_with_arguments(arg_one, arg_two = nil); :existing_method_with_arguments_return_value; end
+          def another_existing_method; end
+          private
+          def private_method; :private_method_return_value; end
+        end
+      end
+      let(:existing_method_return_value){ :existing_method_return_value }
+
+      context "invocation order" do
+        context "when stubbing" do
+          it "raises an error if 'with' follows 'and_return'" do
+            expect { allow_any_instance_of(klass).to receive(:foo).and_return(1).with("1") }.to raise_error(NoMethodError)
+          end
+
+          it "raises an error if 'with' follows 'and_raise'" do
+            expect { allow_any_instance_of(klass).to receive(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError)
+          end
+
+          it "raises an error if 'with' follows 'and_yield'" do
+            expect { allow_any_instance_of(klass).to receive(:foo).and_yield(1).with("1") }.to raise_error(NoMethodError)
+          end
+        end
+
+        context "when setting a message expectation" do
+          it "raises an error if 'with' follows 'and_return'" do
+            pending "see Github issue #42"
+            expect { expect_any_instance_of(klass).to receive(:foo).and_return(1).with("1") }.to raise_error(NoMethodError)
+          end
+
+          it "raises an error if 'with' follows 'and_raise'" do
+            pending "see Github issue #42"
+            expect { expect_any_instance_of(klass).to receive(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError)
+          end
+        end
+      end
+
+      context "when stubbing" do
+        it "does not suppress an exception when a method that doesn't exist is invoked" do
+          allow_any_instance_of(klass).to receive(:foo)
+          expect { klass.new.bar }.to raise_error(NoMethodError)
+        end
+
+        context 'multiple methods' do
+          it "allows multiple methods to be stubbed in a single invocation" do
+            allow_any_instance_of(klass).to receive_messages(:foo => 'foo', :bar => 'bar')
+            instance = klass.new
+            expect(instance.foo).to eq('foo')
+            expect(instance.bar).to eq('bar')
+          end
+
+          context "allows a chain of methods to be stubbed using #receive_message_chain" do
+            example "given symbols representing the methods" do
+              allow_any_instance_of(klass).to receive_message_chain(:one, :two, :three).and_return(:four)
+              expect(klass.new.one.two.three).to eq(:four)
+            end
+
+            example "given a hash as the last argument uses the value as the expected return value" do
+              allow_any_instance_of(klass).to receive_message_chain(:one, :two, :three => :four)
+              expect(klass.new.one.two.three).to eq(:four)
+            end
+
+            example "given a string of '.' separated method names representing the chain" do
+              allow_any_instance_of(klass).to receive_message_chain('one.two.three').and_return(:four)
+              expect(klass.new.one.two.three).to eq(:four)
+            end
+          end
+        end
+
+        context "behaves as 'every instance'" do
+          let(:super_class) { Class.new { def foo; 'bar'; end } }
+          let(:sub_class)   { Class.new(super_class) }
+
+          it "stubs every instance in the spec" do
+            allow_any_instance_of(klass).to receive(:foo).and_return(result = Object.new)
+            expect(klass.new.foo).to eq(result)
+            expect(klass.new.foo).to eq(result)
+          end
+
+          it "stubs instance created before any_instance was called" do
+            instance = klass.new
+            allow_any_instance_of(klass).to receive(:foo).and_return(result = Object.new)
+            expect(instance.foo).to eq(result)
+          end
+
+          it 'handles freeze and duplication correctly' do
+            allow_any_instance_of(String).to receive(:any_method)
+
+            foo = 'foo'.freeze
+            expect(foo.dup.concat 'bar').to eq 'foobar'
+          end
+
+          it 'handles stubbing on super and subclasses' do
+            allow_any_instance_of(super_class).to receive(:foo)
+            allow_any_instance_of(sub_class).to receive(:foo).and_return('baz')
+            expect(sub_class.new.foo).to eq('baz')
+          end
+
+          it 'handles method restoration on subclasses' do
+            allow_any_instance_of(super_class).to receive(:foo)
+            allow_any_instance_of(sub_class).to receive(:foo)
+            allow_any_instance_of(sub_class).to receive(:foo).and_call_original
+            expect(sub_class.new.foo).to eq("bar")
+          end
+        end
+
+        context "when the class has a prepended module", :if => Support::RubyFeatures.module_prepends_supported? do
+          it 'allows stubbing a method that is not defined on the prepended module' do
+            klass.class_eval { prepend Module.new { def other; end } }
+            allow_any_instance_of(klass).to receive(:foo).and_return(45)
+
+            expect(klass.new.foo).to eq(45)
+          end
+
+          it 'prevents stubbing a method that is defined on the prepended module' do
+            klass.class_eval { prepend Module.new { def foo; end } }
+
+            expect {
+              allow_any_instance_of(klass).to receive(:foo).and_return(45)
+            }.to fail_with(/prepended module/)
+          end
+
+          it 'allows stubbing a chain starting with a method that is not defined on the prepended module' do
+            klass.class_eval { prepend Module.new { def other; end } }
+            allow_any_instance_of(klass).to receive_message_chain(:foo, :bar).and_return(45)
+
+            expect(klass.new.foo.bar).to eq(45)
+          end
+
+          it 'prevents stubbing a chain starting with a method that is defined on the prepended module' do
+            klass.class_eval { prepend Module.new { def foo; end } }
+
+            expect {
+              allow_any_instance_of(klass).to receive_message_chain(:foo, :bar).and_return(45)
+            }.to fail_with(/prepended module/)
+          end
+        end
+
+        context "with argument matching" do
+          before do
+            allow_any_instance_of(klass).to receive(:foo).with(:param_one, :param_two).and_return(:result_one)
+            allow_any_instance_of(klass).to receive(:foo).with(:param_three, :param_four).and_return(:result_two)
+          end
+
+          it "returns the stubbed value when arguments match" do
+            instance = klass.new
+            expect(instance.foo(:param_one, :param_two)).to eq(:result_one)
+            expect(instance.foo(:param_three, :param_four)).to eq(:result_two)
+          end
+
+          it "fails the spec with an expectation error when the arguments do not match" do
+            expect do
+              klass.new.foo(:param_one, :param_three)
+            end.to(raise_error(RSpec::Mocks::MockExpectationError))
+          end
+        end
+
+        context "with multiple stubs" do
+          before do
+            allow_any_instance_of(klass).to receive(:foo).and_return(1)
+            allow_any_instance_of(klass).to receive(:bar).and_return(2)
+          end
+
+          it "stubs a method" do
+            instance = klass.new
+            expect(instance.foo).to eq(1)
+            expect(instance.bar).to eq(2)
+          end
+
+          it "returns the same value for calls on different instances" do
+            expect(klass.new.foo).to eq(klass.new.foo)
+            expect(klass.new.bar).to eq(klass.new.bar)
+          end
+        end
+
+        context "with #and_return" do
+          it "can stub a method that doesn't exist" do
+            allow_any_instance_of(klass).to receive(:foo).and_return(1)
+            expect(klass.new.foo).to eq(1)
+          end
+
+          it "can stub a method that exists" do
+            allow_any_instance_of(klass).to receive(:existing_method).and_return(1)
+            expect(klass.new.existing_method).to eq(1)
+          end
+
+          it "returns the same object for calls on different instances" do
+            return_value = Object.new
+            allow_any_instance_of(klass).to receive(:foo).and_return(return_value)
+            expect(klass.new.foo).to be(return_value)
+            expect(klass.new.foo).to be(return_value)
+          end
+
+          it "can change how instances responds in the middle of an example" do
+            instance = klass.new
+
+            allow_any_instance_of(klass).to receive(:foo).and_return(1)
+            expect(instance.foo).to eq(1)
+            allow_any_instance_of(klass).to receive(:foo).and_return(2)
+            expect(instance.foo).to eq(2)
+            allow_any_instance_of(klass).to receive(:foo).and_raise("boom")
+            expect { instance.foo }.to raise_error("boom")
+          end
+        end
+
+        context "with #and_yield" do
+          it "yields the value specified" do
+            yielded_value = Object.new
+            allow_any_instance_of(klass).to receive(:foo).and_yield(yielded_value)
+            expect { |b| klass.new.foo(&b) }.to yield_with_args(yielded_value)
+          end
+        end
+
+        context 'with #and_call_original and competing #with' do
+          let(:klass) { Struct.new(:a_method) }
+
+          it 'can combine and_call_original, with, and_return' do
+            allow_any_instance_of(klass).to receive(:a_method).and_call_original
+            allow_any_instance_of(klass).to receive(:a_method).with(:arg).and_return('value')
+
+            expect(klass.new('org').a_method).to eq 'org'
+            expect(klass.new.a_method(:arg)).to  eq 'value'
+          end
+
+          it 'can combine and_call_original, with, and_return (old syntax)' do
+            allow_any_instance_of(klass).to receive(:a_method).and_call_original
+            allow_any_instance_of(klass).to receive(:a_method).with(:arg).and_return('value')
+
+            expect(klass.new('org').a_method).to eq 'org'
+            expect(klass.new.a_method(:arg)).to  eq 'value'
+          end
+        end
+
+        context "with #and_raise" do
+          it "can stub a method that doesn't exist" do
+            allow_any_instance_of(klass).to receive(:foo).and_raise(CustomErrorForAnyInstanceSpec)
+            expect { klass.new.foo }.to raise_error(CustomErrorForAnyInstanceSpec)
+          end
+
+          it "can stub a method that exists" do
+            allow_any_instance_of(klass).to receive(:existing_method).and_raise(CustomErrorForAnyInstanceSpec)
+            expect { klass.new.existing_method }.to raise_error(CustomErrorForAnyInstanceSpec)
+          end
+        end
+
+        context "with a block" do
+          it "stubs a method" do
+            allow_any_instance_of(klass).to receive(:foo) { 1 }
+            expect(klass.new.foo).to eq(1)
+          end
+
+          it "returns the same computed value for calls on different instances" do
+            allow_any_instance_of(klass).to receive(:foo) { 1 + 2 }
+            expect(klass.new.foo).to eq(klass.new.foo)
+          end
+        end
+
+        context "when partially mocking objects" do
+          let(:obj) { klass.new }
+
+          it "resets partially mocked objects correctly" do
+            allow_any_instance_of(klass).to receive(:existing_method).and_return("stubbed value")
+
+            # Simply resetting the proxy doesn't work
+            # what we need to have happen is
+            # ::RSpec::Mocks.space.any_instance_recorder_for(klass).stop_all_observation!
+            # but that is never invoked in ::
+            expect {
+              verify_all
+            }.to(
+              change { obj.existing_method }.from("stubbed value").to(:existing_method_return_value)
+            )
+          end
+        end
+
+        context "core ruby objects" do
+          it "works uniformly across *everything*" do
+            allow_any_instance_of(Object).to receive(:foo).and_return(1)
+            expect(Object.new.foo).to eq(1)
+          end
+
+          it "works with the non-standard constructor []" do
+            allow_any_instance_of(Array).to receive(:foo).and_return(1)
+            expect([].foo).to eq(1)
+          end
+
+          it "works with the non-standard constructor {}" do
+            allow_any_instance_of(Hash).to receive(:foo).and_return(1)
+            expect({}.foo).to eq(1)
+          end
+
+          it "works with the non-standard constructor \"\"" do
+            allow_any_instance_of(String).to receive(:foo).and_return(1)
+            expect("".foo).to eq(1)
+          end
+
+          it "works with the non-standard constructor \'\'" do
+            allow_any_instance_of(String).to receive(:foo).and_return(1)
+            expect(''.foo).to eq(1)
+          end
+
+          it "works with the non-standard constructor module" do
+            allow_any_instance_of(Module).to receive(:foo).and_return(1)
+            module RSpec::SampleRspecTestModule;end
+            expect(RSpec::SampleRspecTestModule.foo).to eq(1)
+          end
+
+          it "works with the non-standard constructor class" do
+            allow_any_instance_of(Class).to receive(:foo).and_return(1)
+            class RSpec::SampleRspecTestClass;end
+            expect(RSpec::SampleRspecTestClass.foo).to eq(1)
+          end
+        end
+      end
+
+      context "unstubbing using `and_call_original`" do
+        it "replaces the stubbed method with the original method" do
+          allow_any_instance_of(klass).to receive(:existing_method)
+          allow_any_instance_of(klass).to receive(:existing_method).and_call_original
+          expect(klass.new.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes all stubs with the supplied method name" do
+          allow_any_instance_of(klass).to receive(:existing_method).with(1)
+          allow_any_instance_of(klass).to receive(:existing_method).with(2)
+          allow_any_instance_of(klass).to receive(:existing_method).and_call_original
+          expect(klass.new.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes stubs even if they have already been invoked" do
+          allow_any_instance_of(klass).to receive(:existing_method).and_return(:any_instance_value)
+          obj = klass.new
+          obj.existing_method
+          allow_any_instance_of(klass).to receive(:existing_method).and_call_original
+
+          expect(obj.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes stubs from sub class after invokation when super class was originally stubbed" do
+          allow_any_instance_of(klass).to receive(:existing_method).and_return(:any_instance_value)
+          obj = Class.new(klass).new
+          expect(obj.existing_method).to eq(:any_instance_value)
+          allow_any_instance_of(klass).to receive(:existing_method).and_call_original
+
+          expect(obj.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes any stubs set directly on an instance" do
+          allow_any_instance_of(klass).to receive(:existing_method).and_return(:any_instance_value)
+          obj = klass.new
+          allow(obj).to receive(:existing_method).and_return(:local_method)
+          allow_any_instance_of(klass).to receive(:existing_method).and_call_original
+          expect(obj.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "does not remove any expectations with the same method name" do
+          expect_any_instance_of(klass).to receive(:existing_method_with_arguments).with(3).and_return(:three)
+          allow_any_instance_of(klass).to receive(:existing_method_with_arguments).with(1)
+          allow_any_instance_of(klass).to receive(:existing_method_with_arguments).with(2)
+          allow_any_instance_of(klass).to receive(:existing_method_with_arguments).and_call_original
+          expect(klass.new.existing_method_with_arguments(3)).to eq(:three)
+        end
+
+        it 'does not get confused about string vs symbol usage for the message' do
+          allow_any_instance_of(klass).to receive(:existing_method) { :stubbed }
+          allow_any_instance_of(klass).to receive("existing_method").and_call_original
+          expect(klass.new.existing_method).to eq(:existing_method_return_value)
+        end
+      end
+
+      context "expect_any_instance_of(...).not_to receive" do
+        it "fails if the method is called" do
+          expect_any_instance_of(klass).not_to receive(:existing_method)
+          expect { klass.new.existing_method }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+        it "passes if no method is called" do
+          expect { expect_any_instance_of(klass).not_to receive(:existing_method) }.to_not raise_error
+        end
+
+        it "passes if only a different method is called" do
+          expect_any_instance_of(klass).not_to receive(:existing_method)
+          expect { klass.new.another_existing_method }.to_not raise_error
+        end
+
+        it "affects previously stubbed instances" do
+          instance = klass.new
+
+          allow_any_instance_of(klass).to receive(:foo).and_return(1)
+          expect(instance.foo).to eq(1)
+          expect_any_instance_of(klass).not_to receive(:foo)
+          expect { instance.foo }.to fail
+        end
+
+        context "with constraints" do
+          it "fails if the method is called with the specified parameters" do
+            expect_any_instance_of(klass).not_to receive(:existing_method_with_arguments).with(:argument_one, :argument_two)
+            expect {
+              klass.new.existing_method_with_arguments(:argument_one, :argument_two)
+            }.to raise_error(RSpec::Mocks::MockExpectationError)
+          end
+
+          it "passes if the method is called with different parameters" do
+            expect_any_instance_of(klass).not_to receive(:existing_method_with_arguments).with(:argument_one, :argument_two)
+            expect { klass.new.existing_method_with_arguments(:argument_three, :argument_four) }.to_not raise_error
+          end
+        end
+
+        context 'when used in combination with should_receive' do
+          it 'passes if only the expected message is received' do
+            expect_any_instance_of(klass).to receive(:foo)
+            expect_any_instance_of(klass).not_to receive(:bar)
+            klass.new.foo
+            verify_all
+          end
+        end
+
+        it "prevents confusing double-negative expressions involving `never`" do
+          expect {
+            expect_any_instance_of(klass).not_to receive(:not_expected).never
+          }.to raise_error(/trying to negate it again/)
+        end
+      end
+
+      context "setting a message expectation" do
+        let(:foo_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: foo' }
+        let(:existing_method_expectation_error_message) { 'Exactly one instance should have received the following message(s) but didn\'t: existing_method' }
+
+        it "handles inspect accessing expected methods" do
+          klass.class_eval do
+            def inspect
+              "The contents of output: #{stdout}"
+            end
+          end
+
+          expect_any_instance_of(klass).to receive(:stdout).at_least(:twice)
+          expect do
+            klass.new.stdout
+            klass.new.stdout
+          end.to raise_error(/The message 'stdout' was received by/)
+          reset_all
+        end
+
+        it "affects previously stubbed instances" do
+          instance = klass.new
+
+          allow_any_instance_of(klass).to receive(:foo).and_return(1)
+          expect(instance.foo).to eq(1)
+          expect_any_instance_of(klass).to receive(:foo).with(2).and_return(2)
+          expect(instance.foo(2)).to eq(2)
+        end
+
+        it "does not set the expectation on every instance" do
+          # Setup an unrelated object of the same class that won't receive the expected message.
+          allow('non-related object').to receive(:non_related_method)
+
+          expect_any_instance_of(Object).to receive(:foo)
+          'something'.foo
+        end
+
+        it "does not modify the return value of stubs set on an instance" do
+          expect_any_instance_of(Object).to receive(:foo).twice
+          object = Object.new
+          allow(object).to receive(:foo).and_return(3)
+          expect(object.foo).to eq(3)
+          expect(object.foo).to eq(3)
+        end
+
+        it "does not modify the return value of stubs set on an instance of a subclass" do
+          subklass = Class.new(klass)
+          subinstance = subklass.new
+          allow_any_instance_of(klass).to receive(:foo).and_return(1)
+          expect(subinstance.foo).to eq(1)
+          expect_any_instance_of(klass).to receive(:foo).with(2).and_return(2)
+          expect(subinstance.foo(2)).to eq(2)
+        end
+
+        it "properly notifies any instance recorders at multiple levels of hierarchy when a directly stubbed object receives a message" do
+          subclass = Class.new(klass)
+          instance = subclass.new
+
+          expect_any_instance_of(klass).to receive(:msg_1)
+          expect_any_instance_of(subclass).to receive(:msg_2)
+
+          allow(instance).to receive_messages(:msg_1 => "a", :msg_2 => "b")
+
+          expect(instance.msg_1).to eq("a")
+          expect(instance.msg_2).to eq("b")
+        end
+
+        it "properly notifies any instance recorders when they are created after the object's mock proxy" do
+          object = Object.new
+          allow(object).to receive(:bar)
+          expect_any_instance_of(Object).to receive(:foo).twice
+          allow(object).to receive(:foo).and_return(3)
+          expect(object.foo).to eq(3)
+          expect(object.foo).to eq(3)
+        end
+
+        context "when the class has a prepended module", :if => Support::RubyFeatures.module_prepends_supported? do
+          it 'allows mocking a method that is not defined on the prepended module' do
+            klass.class_eval { prepend Module.new { def other; end } }
+            expect_any_instance_of(klass).to receive(:foo).and_return(45)
+
+            expect(klass.new.foo).to eq(45)
+          end
+
+          it 'prevents mocking a method that is defined on the prepended module' do
+            klass.class_eval { prepend Module.new { def foo; end } }
+
+            expect {
+              expect_any_instance_of(klass).to receive(:foo).and_return(45)
+            }.to fail_with(/prepended module/)
+          end
+        end
+
+        context "when the class has an included module" do
+          it 'allows mocking a method that is defined on the module' do
+            mod = Module.new { def foo; end }
+            klass.class_eval { include mod }
+            expect_any_instance_of(mod).to receive(:foo).and_return(45)
+
+            expect(klass.new.foo).to eq(45)
+          end
+        end
+
+        context "when an instance has been directly stubbed" do
+          it "fails when a second instance to receive the message" do
+            expect_any_instance_of(klass).to receive(:foo)
+            instance_1 = klass.new
+
+            allow(instance_1).to receive(:foo).and_return(17)
+            expect(instance_1.foo).to eq(17)
+
+            expect {
+              klass.new.foo
+            }.to fail_with(/has already been received/)
+          end
+        end
+
+        context "when argument matching is used and an instance has stubbed the message" do
+          it "fails on verify if the arguments do not match" do
+            expect_any_instance_of(klass).to receive(:foo).with(3)
+            instance = klass.new
+            allow(instance).to receive(:foo).and_return(2)
+
+            expect(instance.foo(4)).to eq(2)
+            expect { verify_all }.to fail
+          end
+
+          it "passes on verify if the arguments do match" do
+            expect_any_instance_of(klass).to receive(:foo).with(3)
+            instance = klass.new
+            allow(instance).to receive(:foo).and_return(2)
+
+            expect(instance.foo(3)).to eq(2)
+            expect { verify_all }.not_to raise_error
+          end
+        end
+
+        context "with an expectation is set on a method which does not exist" do
+          it "returns the expected value" do
+            expect_any_instance_of(klass).to receive(:foo).and_return(1)
+            expect(klass.new.foo(1)).to eq(1)
+          end
+
+          it "fails if an instance is created but no invocation occurs" do
+            expect do
+              expect_any_instance_of(klass).to receive(:foo)
+              klass.new
+              verify_all
+            end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
+          end
+
+          it "fails if no instance is created" do
+            expect do
+              expect_any_instance_of(klass).to receive(:foo).and_return(1)
+              verify_all
+            end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
+          end
+
+          it "fails if no instance is created and there are multiple expectations" do
+            expect do
+              expect_any_instance_of(klass).to receive(:foo)
+              expect_any_instance_of(klass).to receive(:bar)
+              verify_all
+            end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: bar, foo')
+          end
+
+          it "allows expectations on instances to take priority" do
+            expect_any_instance_of(klass).to receive(:foo)
+            klass.new.foo
+
+            instance = klass.new
+            expect(instance).to receive(:foo).and_return(result = Object.new)
+            expect(instance.foo).to eq(result)
+          end
+
+          context "behaves as 'exactly one instance'" do
+            it "passes if subsequent invocations do not receive that message" do
+              expect_any_instance_of(klass).to receive(:foo)
+              klass.new.foo
+              klass.new
+            end
+
+            it "fails if the method is invoked on a second instance" do
+              instance_one = klass.new
+              instance_two = klass.new
+              expect do
+                expect_any_instance_of(klass).to receive(:foo)
+
+                instance_one.foo
+                instance_two.foo
+              end.to raise_error(RSpec::Mocks::MockExpectationError, /The message 'foo' was received by .*#{instance_two.object_id}.* but has already been received by #{instance_one.inspect}/)
+            end
+          end
+
+          context "normal expectations on the class object" do
+            it "fail when unfulfilled" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo)
+                expect(klass).to receive(:woot)
+                klass.new.foo
+                verify_all
+              end.to(raise_error(RSpec::Mocks::MockExpectationError) do |error|
+                expect(error.message).not_to eq(existing_method_expectation_error_message)
+              end)
+            end
+
+            it "pass when expectations are met" do
+              expect_any_instance_of(klass).to receive(:foo)
+              expect(klass).to receive(:woot).and_return(result = Object.new)
+              klass.new.foo
+              expect(klass.woot).to eq(result)
+            end
+          end
+        end
+
+        context "with an expectation is set on a method that exists" do
+          it "returns the expected value" do
+            expect_any_instance_of(klass).to receive(:existing_method).and_return(1)
+            expect(klass.new.existing_method(1)).to eq(1)
+          end
+
+          it "fails if an instance is created but no invocation occurs" do
+            expect do
+              expect_any_instance_of(klass).to receive(:existing_method)
+              klass.new
+              verify_all
+            end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
+          end
+
+          it "fails if no instance is created" do
+            expect do
+              expect_any_instance_of(klass).to receive(:existing_method)
+              verify_all
+            end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
+          end
+
+          it "fails if no instance is created and there are multiple expectations" do
+            expect do
+              expect_any_instance_of(klass).to receive(:existing_method)
+              expect_any_instance_of(klass).to receive(:another_existing_method)
+              verify_all
+            end.to raise_error(RSpec::Mocks::MockExpectationError, 'Exactly one instance should have received the following message(s) but didn\'t: another_existing_method, existing_method')
+          end
+
+          context "after any one instance has received a message" do
+            it "passes if subsequent invocations do not receive that message" do
+              expect_any_instance_of(klass).to receive(:existing_method)
+              klass.new.existing_method
+              klass.new
+            end
+
+            it "fails if the method is invoked on a second instance" do
+              instance_one = klass.new
+              instance_two = klass.new
+              expect do
+                expect_any_instance_of(klass).to receive(:existing_method)
+
+                instance_one.existing_method
+                instance_two.existing_method
+              end.to raise_error(RSpec::Mocks::MockExpectationError, /The message 'existing_method' was received by .*#{instance_two.object_id}.* but has already been received by #{instance_one.inspect}/)
+            end
+          end
+        end
+
+        it 'works with a BasicObject subclass that mixes in Kernel', :if => defined?(BasicObject) do
+          klazz = Class.new(BasicObject) do
+            include ::Kernel
+            def foo; end
+          end
+
+          expect_any_instance_of(klazz).to receive(:foo)
+          klazz.new.foo
+        end
+
+        it 'works with a SimpleDelegator subclass', :if => (RUBY_VERSION.to_f > 1.8) do
+          klazz = Class.new(SimpleDelegator) do
+            def foo; end
+          end
+
+          expect_any_instance_of(klazz).to receive(:foo)
+          klazz.new(Object.new).foo
+        end
+
+        context "with argument matching" do
+          before do
+            expect_any_instance_of(klass).to receive(:foo).with(:param_one, :param_two).and_return(:result_one)
+            expect_any_instance_of(klass).to receive(:foo).with(:param_three, :param_four).and_return(:result_two)
+          end
+
+          it "returns the expected value when arguments match" do
+            instance = klass.new
+            expect(instance.foo(:param_one, :param_two)).to eq(:result_one)
+            expect(instance.foo(:param_three, :param_four)).to eq(:result_two)
+          end
+
+          it "fails when the arguments match but different instances are used" do
+            instances = Array.new(2) { klass.new }
+            expect do
+              expect(instances[0].foo(:param_one, :param_two)).to eq(:result_one)
+              expect(instances[1].foo(:param_three, :param_four)).to eq(:result_two)
+            end.to raise_error(RSpec::Mocks::MockExpectationError)
+
+            # ignore the fact that should_receive expectations were not met
+            instances.each { |instance| reset instance }
+          end
+
+          it "is not affected by the invocation of existing methods on other instances" do
+            expect(klass.new.existing_method_with_arguments(:param_one, :param_two)).to eq(:existing_method_with_arguments_return_value)
+            instance = klass.new
+            expect(instance.foo(:param_one, :param_two)).to eq(:result_one)
+            expect(instance.foo(:param_three, :param_four)).to eq(:result_two)
+          end
+
+          it "fails when arguments do not match" do
+            instance = klass.new
+            expect do
+              instance.foo(:param_one, :param_three)
+            end.to raise_error(RSpec::Mocks::MockExpectationError)
+
+            # ignore the fact that should_receive expectations were not met
+            reset instance
+          end
+        end
+
+        context "message count" do
+          context "the 'once' constraint" do
+            it "passes for one invocation" do
+              expect_any_instance_of(klass).to receive(:foo).once
+              klass.new.foo
+            end
+
+            it "fails when no instances are declared" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).once
+                verify_all
+              end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
+            end
+
+            it "fails when an instance is declared but there are no invocations" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).once
+                klass.new
+                verify_all
+              end.to raise_error(RSpec::Mocks::MockExpectationError, foo_expectation_error_message)
+            end
+
+            it "fails for more than one invocation" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).once
+                instance = klass.new
+                2.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+          end
+
+          context "the 'twice' constraint" do
+            it "passes for two invocations" do
+              expect_any_instance_of(klass).to receive(:foo).twice
+              instance = klass.new
+              2.times { instance.foo }
+            end
+
+            it "fails for more than two invocations" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).twice
+                instance = klass.new
+                3.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+          end
+
+          context "the 'thrice' constraint" do
+            it "passes for three invocations" do
+              expect_any_instance_of(klass).to receive(:foo).thrice
+              instance = klass.new
+              3.times { instance.foo }
+            end
+
+            it "fails for more than three invocations" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).thrice
+                instance = klass.new
+                4.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+
+            it "fails for less than three invocations" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).thrice
+                instance = klass.new
+                2.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+          end
+
+          context "the 'exactly(n)' constraint" do
+            it "passes for n invocations where n = 3" do
+              expect_any_instance_of(klass).to receive(:foo).exactly(3).times
+              instance = klass.new
+              3.times { instance.foo }
+            end
+
+            it "fails for n invocations where n < 3" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).exactly(3).times
+                instance = klass.new
+                2.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+
+            it "fails for n invocations where n > 3" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).exactly(3).times
+                instance = klass.new
+                4.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+          end
+
+          context "the 'at_least(n)' constraint" do
+            it "passes for n invocations where n = 3" do
+              expect_any_instance_of(klass).to receive(:foo).at_least(3).times
+              instance = klass.new
+              3.times { instance.foo }
+            end
+
+            it "fails for n invocations where n < 3" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).at_least(3).times
+                instance = klass.new
+                2.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+
+            it "passes for n invocations where n > 3" do
+              expect_any_instance_of(klass).to receive(:foo).at_least(3).times
+              instance = klass.new
+              4.times { instance.foo }
+            end
+          end
+
+          context "the 'at_most(n)' constraint" do
+            it "passes for n invocations where n = 3" do
+              expect_any_instance_of(klass).to receive(:foo).at_most(3).times
+              instance = klass.new
+              3.times { instance.foo }
+            end
+
+            it "passes for n invocations where n < 3" do
+              expect_any_instance_of(klass).to receive(:foo).at_most(3).times
+              instance = klass.new
+              2.times { instance.foo }
+            end
+
+            it "fails for n invocations where n > 3" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).at_most(3).times
+                instance = klass.new
+                4.times { instance.foo }
+                verify instance
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+          end
+
+          context "the 'never' constraint" do
+            it "passes for 0 invocations" do
+              expect_any_instance_of(klass).to receive(:foo).never
+              verify_all
+            end
+
+            it "fails on the first invocation" do
+              expect do
+                expect_any_instance_of(klass).to receive(:foo).never
+                klass.new.foo
+              end.to raise_error(RSpec::Mocks::MockExpectationError)
+            end
+
+            context "when combined with other expectations" do
+              it "passes when the other expecations are met" do
+                expect_any_instance_of(klass).to receive(:foo).never
+                expect_any_instance_of(klass).to receive(:existing_method).and_return(5)
+                expect(klass.new.existing_method).to eq(5)
+              end
+
+              it "fails when the other expecations are not met" do
+                expect do
+                  expect_any_instance_of(klass).to receive(:foo).never
+                  expect_any_instance_of(klass).to receive(:existing_method).and_return(5)
+                  verify_all
+                end.to raise_error(RSpec::Mocks::MockExpectationError, existing_method_expectation_error_message)
+              end
+            end
+          end
+        end
+      end
+
+      context "when resetting post-verification" do
+        let(:space) { RSpec::Mocks.space }
+
+        context "existing method" do
+          before(:each) do
+            RSpec::Mocks.space.any_instance_recorder_for(klass) # to force it to be tracked
+          end
+
+          context "with stubbing" do
+            context "public methods" do
+              before(:each) do
+                allow_any_instance_of(klass).to receive(:existing_method).and_return(1)
+                expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_truthy
+              end
+
+              it "restores the class to its original state after each example when no instance is created" do
+                verify_all
+
+                expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
+                expect(klass.new.existing_method).to eq(existing_method_return_value)
+              end
+
+              it "restores the class to its original state after each example when one instance is created" do
+                klass.new.existing_method
+
+                verify_all
+
+                expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
+                expect(klass.new.existing_method).to eq(existing_method_return_value)
+              end
+
+              it "restores the class to its original state after each example when more than one instance is created" do
+                klass.new.existing_method
+                klass.new.existing_method
+
+                verify_all
+
+                expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
+                expect(klass.new.existing_method).to eq(existing_method_return_value)
+              end
+            end
+
+            context "private methods" do
+              before :each do
+                allow_any_instance_of(klass).to receive(:private_method).and_return(:something)
+
+                verify_all
+              end
+
+              it "cleans up the backed up method" do
+                expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
+              end
+
+              it "restores a stubbed private method after the spec is run" do
+                expect(klass.private_method_defined?(:private_method)).to be_truthy
+              end
+
+              it "ensures that the restored method behaves as it originally did" do
+                expect(klass.new.send(:private_method)).to eq(:private_method_return_value)
+              end
+            end
+          end
+
+          context "with expectations" do
+            context "private methods" do
+              before :each do
+                expect_any_instance_of(klass).to receive(:private_method).and_return(:something)
+                klass.new.private_method
+
+                verify_all
+              end
+
+              it "cleans up the backed up method" do
+                expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
+              end
+
+              it "restores a stubbed private method after the spec is run" do
+                expect(klass.private_method_defined?(:private_method)).to be_truthy
+              end
+
+              it "ensures that the restored method behaves as it originally did" do
+                expect(klass.new.send(:private_method)).to eq(:private_method_return_value)
+              end
+            end
+
+            context "ensures that the subsequent specs do not see expectations set in previous specs" do
+              context "when the instance created after the expectation is set" do
+                it "first spec" do
+                  expect_any_instance_of(klass).to receive(:existing_method).and_return(Object.new)
+                  klass.new.existing_method
+                end
+
+                it "second spec" do
+                  expect(klass.new.existing_method).to eq(existing_method_return_value)
+                end
+              end
+
+              context "when the instance created before the expectation is set" do
+                before :each do
+                  @instance = klass.new
+                end
+
+                it "first spec" do
+                  expect_any_instance_of(klass).to receive(:existing_method).and_return(Object.new)
+                  @instance.existing_method
+                end
+
+                it "second spec" do
+                  expect(@instance.existing_method).to eq(existing_method_return_value)
+                end
+              end
+            end
+
+            it "ensures that the next spec does not see that expectation" do
+              expect_any_instance_of(klass).to receive(:existing_method).and_return(Object.new)
+              klass.new.existing_method
+
+              verify_all
+
+              expect(klass.new.existing_method).to eq(existing_method_return_value)
+            end
+          end
+        end
+
+        context "with multiple calls to any_instance in the same example" do
+          it "does not prevent the change from being rolled back" do
+            allow_any_instance_of(klass).to receive(:existing_method).and_return(false)
+            allow_any_instance_of(klass).to receive(:existing_method).and_return(true)
+
+            verify_all
+            expect(klass.new).to respond_to(:existing_method)
+            expect(klass.new.existing_method).to eq(existing_method_return_value)
+          end
+        end
+
+        it "adds an instance to the current space when stubbed method is invoked" do
+          allow_any_instance_of(klass).to receive(:foo)
+          instance = klass.new
+          instance.foo
+          expect(RSpec::Mocks.space.proxies.keys).to include(instance.object_id)
+        end
+      end
+
+      context "passing the receiver to the implementation block" do
+        context "when configured to pass the instance" do
+          include_context 'with isolated configuration'
+          before(:each) do
+            RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks = true
+          end
+
+          describe "an any instance stub" do
+            it "passes the instance as the first arg of the implementation block" do
+              instance = klass.new
+
+              expect { |b|
+                expect_any_instance_of(klass).to receive(:bees).with(:sup, &b)
+                instance.bees(:sup)
+              }.to yield_with_args(instance, :sup)
+            end
+
+            it "does not pass the instance to and_call_original" do
+              klazz = Class.new do
+                def call(*args)
+                  args.first
+                end
+              end
+              expect_any_instance_of(klazz).to receive(:call).and_call_original
+              instance = klazz.new
+              expect(instance.call(:bees)).to be :bees
+            end
+          end
+
+          describe "an any instance expectation" do
+            it "doesn't effect with" do
+              instance = klass.new
+              expect_any_instance_of(klass).to receive(:bees).with(:sup)
+              instance.bees(:sup)
+            end
+
+            it "passes the instance as the first arg of the implementation block" do
+              instance = klass.new
+
+              expect { |b|
+                expect_any_instance_of(klass).to receive(:bees).with(:sup, &b)
+                instance.bees(:sup)
+              }.to yield_with_args(instance, :sup)
+            end
+          end
+        end
+
+        context "when configured not to pass the instance" do
+          include_context 'with isolated configuration'
+          before(:each) do
+            RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks = false
+          end
+
+          describe "an any instance stub" do
+            it "does not pass the instance to the implementation block" do
+              instance = klass.new
+
+              expect { |b|
+                expect_any_instance_of(klass).to receive(:bees).with(:sup, &b)
+                instance.bees(:sup)
+              }.to yield_with_args(:sup)
+            end
+
+            it "does not cause with to fail when the instance is passed" do
+              instance = klass.new
+              expect_any_instance_of(klass).to receive(:bees).with(:faces)
+              instance.bees(:faces)
+            end
+          end
+        end
+      end
+
+      context 'when used in conjunction with a `dup`' do
+        it "doesn't cause an infinite loop" do
+          skip "This intermittently fails on JRuby" if RUBY_PLATFORM == 'java'
+
+          allow_any_instance_of(Object).to receive(:some_method)
+          o = Object.new
+          o.some_method
+          expect { o.dup.some_method }.to_not raise_error
+        end
+
+        it "doesn't bomb if the object doesn't support `dup`" do
+          klazz = Class.new do
+            undef_method :dup
+          end
+          allow_any_instance_of(klazz).to receive(:foo)
+        end
+
+        it "doesn't fail when dup accepts parameters" do
+          klazz = Class.new do
+            def dup(funky_option)
+            end
+          end
+
+          allow_any_instance_of(klazz).to receive(:foo)
+
+          expect { klazz.new.dup('Dup dup dup') }.to_not raise_error
+        end
+      end
+
+      context "when directed at a method defined on a superclass" do
+        let(:sub_klass) { Class.new(klass) }
+
+        it "stubs the method correctly" do
+          allow_any_instance_of(klass).to receive(:existing_method).and_return("foo")
+          expect(sub_klass.new.existing_method).to eq "foo"
+        end
+
+        it "mocks the method correctly" do
+          instance_one = sub_klass.new
+          instance_two = sub_klass.new
+          expect do
+            expect_any_instance_of(klass).to receive(:existing_method)
+            instance_one.existing_method
+            instance_two.existing_method
+          end.to raise_error(RSpec::Mocks::MockExpectationError, /The message 'existing_method' was received by .*#{instance_two.object_id}.* but has already been received by #{instance_one.inspect}/)
+        end
+      end
+
+      context "when a class overrides Object#method" do
+        let(:http_request_class) { Struct.new(:method, :uri) }
+
+        it "stubs the method correctly" do
+          allow_any_instance_of(http_request_class).to receive(:existing_method).and_return("foo")
+          expect(http_request_class.new.existing_method).to eq "foo"
+        end
+
+        it "mocks the method correctly" do
+          expect_any_instance_of(http_request_class).to receive(:existing_method).and_return("foo")
+          expect(http_request_class.new.existing_method).to eq "foo"
+        end
+      end
+
+      context "when used after the test has finished" do
+        it "restores the original behavior of a stubbed method" do
+          allow_any_instance_of(klass).to receive(:existing_method).and_return(:stubbed_return_value)
+
+          instance = klass.new
+          expect(instance.existing_method).to eq :stubbed_return_value
+
+          verify_all
+
+          expect(instance.existing_method).to eq :existing_method_return_value
+        end
+
+        it "restores the original behaviour, even if the expectation fails" do
+          expect_any_instance_of(klass).to receive(:existing_method).with(1).and_return(:stubbed_return_value)
+
+          instance = klass.new
+          begin
+            instance.existing_method
+            verify_all
+          rescue RSpec::Mocks::MockExpectationError
+          end
+
+          reset_all
+
+          expect(instance.existing_method).to eq :existing_method_return_value
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/argument_matchers_spec.rb b/rspec-mocks/spec/rspec/mocks/argument_matchers_spec.rb
new file mode 100644
index 0000000..4e1e414
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/argument_matchers_spec.rb
@@ -0,0 +1,425 @@
+module RSpec
+  module Mocks
+    RSpec.describe "argument matchers matching" do
+      let(:a_double) { double }
+
+      after(:each, :reset => true) do
+        reset a_double
+      end
+
+      describe "boolean" do
+        it "accepts true as boolean" do
+          expect(a_double).to receive(:random_call).with(boolean)
+          a_double.random_call(true)
+        end
+
+        it "accepts false as boolean" do
+          expect(a_double).to receive(:random_call).with(boolean)
+          a_double.random_call(false)
+        end
+
+        it "rejects non boolean", :reset => true do
+          expect(a_double).to receive(:random_call).with(boolean)
+          expect {
+            a_double.random_call("false")
+          }.to fail_matching "expected: (boolean)"
+        end
+      end
+
+      describe "kind_of" do
+        it "accepts fixnum as kind_of(Numeric)" do
+          expect(a_double).to receive(:random_call).with(kind_of(Numeric))
+          a_double.random_call(1)
+        end
+
+        it "accepts float as kind_of(Numeric)" do
+          expect(a_double).to receive(:random_call).with(kind_of(Numeric))
+          a_double.random_call(1.5)
+        end
+
+        it "handles non matching kinds nicely", :reset => true do
+          expect(a_double).to receive(:random_call).with(kind_of(Numeric))
+          expect {
+            a_double.random_call(true)
+          }.to fail_matching "expected: (kind of Numeric)"
+        end
+
+        it "matches arguments that have defined `kind_of?` to return true" do
+          fix_num = double(:kind_of? => true)
+          expect(a_double).to receive(:random_call).with(kind_of(Numeric))
+          a_double.random_call(fix_num)
+        end
+
+        it "handles a class thats overridden ===" do
+          allow(Numeric).to receive(:===) { false }
+          fix_num = double(:kind_of? => true)
+          expect(a_double).to receive(:random_call).with(kind_of(Numeric))
+          a_double.random_call(fix_num)
+        end
+      end
+
+      describe "instance_of" do
+        it "accepts fixnum as instance_of(Fixnum)" do
+          expect(a_double).to receive(:random_call).with(instance_of(Fixnum))
+          a_double.random_call(1)
+        end
+
+        it "does NOT accept fixnum as instance_of(Numeric)" do
+          expect(a_double).not_to receive(:random_call).with(instance_of(Numeric))
+          a_double.random_call(1)
+        end
+
+        it "does NOT accept float as instance_of(Numeric)" do
+          expect(a_double).not_to receive(:random_call).with(instance_of(Numeric))
+          a_double.random_call(1.5)
+        end
+
+        it "rejects non numeric", :reset => true do
+          expect(a_double).to receive(:random_call).with(an_instance_of(Numeric))
+          expect { a_double.random_call("1") }.to fail
+        end
+
+        it "rejects non string", :reset => true do
+          expect(a_double).to receive(:random_call).with(an_instance_of(String))
+          expect { a_double.random_call(123) }.to fail
+        end
+
+        it "handles non matching instances nicely", :reset => true do
+          expect(a_double).to receive(:random_call).with(instance_of(Numeric))
+          expect {
+            a_double.random_call(1.5)
+          }.to fail_matching "expected: (an_instance_of(Numeric))"
+        end
+      end
+
+      describe "anything" do
+        it "accepts string as anything" do
+          expect(a_double).to receive(:random_call).with("a", anything, "c")
+          a_double.random_call("a", "whatever", "c")
+        end
+
+        it "doesn't accept no arguments" do
+          expect(a_double).to_not receive(:random_call).with(anything)
+          a_double.random_call
+        end
+
+        it "handles non matching instances nicely", :reset => true do
+          expect(a_double).to receive(:random_call).with(anything)
+          expect { a_double.random_call }.to fail_matching "expected: (anything)"
+        end
+      end
+
+      describe "duck_type" do
+        it "matches duck type with one method" do
+          expect(a_double).to receive(:random_call).with(duck_type(:length))
+          a_double.random_call([])
+        end
+
+        it "matches duck type with two methods" do
+          expect(a_double).to receive(:random_call).with(duck_type(:abs, :div))
+          a_double.random_call(1)
+        end
+
+        it "rejects goose when expecting a duck", :reset => true do
+          expect(a_double).to receive(:random_call).with(duck_type(:abs, :div))
+          expect {
+            a_double.random_call("I don't respond to :abs or :div") 
+          }.to fail_matching "expected: (duck_type(:abs, :div))"
+        end
+      end
+
+      describe "any_args" do
+        context "as the only arg passed to `with`" do
+          before { expect(a_double).to receive(:random_call).with(any_args) }
+
+          it "matches no args" do
+            a_double.random_call
+          end
+
+          it "matches one arg" do
+            a_double.random_call("a string")
+          end
+
+          it "matches many args" do
+            a_double.random_call("a string", :other, 3)
+          end
+        end
+
+        context "as the last of three args" do
+          before { expect(a_double).to receive(:random_call).with(1, /foo/, any_args) }
+
+          it "matches a call of two args when it matches the first two explicit args" do
+            a_double.random_call(1, "food")
+          end
+
+          it "matches a call of three args when it matches the first two explicit args" do
+            a_double.random_call(1, "food", :more)
+          end
+
+          it "matches a call of four args when it matches the first two explicit args" do
+            a_double.random_call(1, "food", :more, :args)
+          end
+
+          it "does not match a call where the first two args do not match", :reset => true do
+            expect { a_double.random_call(1, "bar", 2, 3) }.to fail_matching "expected: (1, /foo/, *(any args))"
+          end
+
+          it "does not match a call of no args", :reset => true do
+            expect { a_double.random_call }.to fail_matching "expected: (1, /foo/, *(any args))"
+          end
+        end
+
+        context "as the first of three args" do
+          before { expect(a_double).to receive(:random_call).with(any_args, 1, /foo/) }
+
+          it "matches a call of two args when it matches the last two explicit args" do
+            a_double.random_call(1, "food")
+          end
+
+          it "matches a call of three args when it matches the last two explicit args" do
+            a_double.random_call(nil, 1, "food")
+          end
+
+          it "matches a call of four args when it matches the last two explicit args" do
+            a_double.random_call(:some, :args, 1, "food")
+          end
+
+          it "does not match a call where the last two args do not match", :reset => true do
+            expect { a_double.random_call(1, "bar", 2, 3) }.to fail_matching "expected: (*(any args), 1, /foo/)"
+          end
+
+          it "does not match a call of no args", :reset => true do
+            expect { a_double.random_call }.to fail_matching "expected: (*(any args), 1, /foo/)"
+          end
+        end
+
+        context "as the middle of three args" do
+          before { expect(a_double).to receive(:random_call).with(1, any_args, /foo/) }
+
+          it "matches a call of two args when it matches the first and last args" do
+            a_double.random_call(1, "food")
+          end
+
+          it "matches a call of three args when it matches the first and last args" do
+            a_double.random_call(1, nil, "food")
+          end
+
+          it "matches a call of four args when it matches the first and last args" do
+            a_double.random_call(1, :some, :args, "food")
+          end
+
+          it "does not match a call where the first and last args do not match", :reset => true do
+            expect { a_double.random_call(nil, "bar", 2, 3) }.to fail_matching "expected: (1, *(any args), /foo/)"
+          end
+
+          it "does not match a call of no args", :reset => true do
+            expect { a_double.random_call }.to fail_matching "expected: (1, *(any args), /foo/)"
+          end
+        end
+
+        context "when passed twice" do
+          it 'immediately signals that this is invalid', :reset => true do
+            expect {
+              expect(a_double).to receive(:random_call).with(any_args, 1, any_args)
+            }.to raise_error(ArgumentError, /any_args/)
+          end
+        end
+      end
+
+      describe "no_args" do
+        it "matches no args against no_args" do
+          expect(a_double).to receive(:random_call).with(no_args)
+          a_double.random_call
+        end
+
+        it "fails no_args with one arg", :reset => true do
+          expect(a_double).to receive(:msg).with(no_args)
+          expect { a_double.msg(37) }.to fail_matching "expected: (no args)"
+        end
+
+        context "when passed with other arguments" do
+          it 'immediately signals that this is invalid', :reset => true do
+            expect {
+              expect(a_double).to receive(:random_call).with(no_args, 3)
+            }.to raise_error(ArgumentError, /no_args/)
+          end
+        end
+      end
+
+      describe "hash_including" do
+        it "matches hash with hash_including same hash" do
+          expect(a_double).to receive(:random_call).with(hash_including(:a => 1))
+          a_double.random_call(:a => 1)
+        end
+
+        it "fails hash_including with missing key", :reset => true do
+          expect(a_double).to receive(:random_call).with(hash_including(:a => 1))
+          expect {
+            a_double.random_call(:a => 2)
+          }.to fail_matching "expected: (hash_including(:a=>1))"
+        end
+      end
+
+      describe "hash_excluding" do
+        it "matches hash with hash_excluding same hash" do
+          expect(a_double).to receive(:random_call).with(hash_excluding(:a => 1))
+          a_double.random_call(:a => 2)
+        end
+
+        it "handles non matching instances nicely", :reset => true do
+          expect(a_double).to receive(:random_call).with(hash_excluding(:a => 1))
+          expect {
+            a_double.random_call(:a => 1)
+          }.to fail_matching "expected: (hash_not_including(:a=>1))"
+        end
+      end
+
+      describe "array_including" do
+        it "matches array with array_including same array" do
+          expect(a_double).to receive(:random_call).with(array_including(1, 2))
+          a_double.random_call([1, 2])
+        end
+
+        it "fails array_including when args aren't array", :reset => true do
+          expect(a_double).to receive(:msg).with(array_including(1, 2, 3))
+          expect {
+             a_double.msg(1, 2, 3)
+          }.to fail_matching "expected: (array_including(1, 2, 3))"
+        end
+
+        it "fails array_including when arg doesn't contain all elements", :reset => true do
+          expect(a_double).to receive(:msg).with(array_including(1, 2, 3))
+          expect {
+             a_double.msg([1, 2])
+          }.to fail_matching "expected: (array_including(1, 2, 3))"
+        end
+      end
+
+      context "handling arbitary matchers" do
+        it "matches any arbitrary object using #===" do
+          matcher = double
+          expect(matcher).to receive(:===).with(4).and_return(true)
+
+          expect(a_double).to receive(:foo).with(matcher)
+          a_double.foo(4)
+        end
+
+        it "matches against a Matcher", :reset => true do
+          expect(a_double).to receive(:msg).with(equal(3))
+          # This spec is generating warnings on 1.8.7, not sure why so
+          # this does with_isolated_stderr to kill them. @samphippen 3rd Jan 2013.
+          expect { with_isolated_stderr { a_double.msg(37) } }.to fail_matching "expected: (equal 3)"
+        end
+
+        it "fails when given an arbitrary object that returns false from #===", :reset => true do
+          matcher = double
+          expect(matcher).to receive(:===).with(4).at_least(:once).and_return(false)
+
+          expect(a_double).to receive(:foo).with(matcher)
+
+          expect { a_double.foo(4) }.to fail
+        end
+      end
+
+      context "handling non-matcher arguments" do
+        it "matches string against regexp" do
+          expect(a_double).to receive(:random_call).with(/bcd/)
+          a_double.random_call("abcde")
+        end
+
+        it "matches regexp against regexp" do
+          expect(a_double).to receive(:random_call).with(/bcd/)
+          a_double.random_call(/bcd/)
+        end
+
+        it "fails if regexp does not match submitted string", :reset => true do
+          expect(a_double).to receive(:random_call).with(/bcd/)
+          expect { a_double.random_call("abc") }.to fail
+        end
+
+        it "fails if regexp does not match submitted regexp", :reset => true do
+          expect(a_double).to receive(:random_call).with(/bcd/)
+          expect { a_double.random_call(/bcde/) }.to fail
+        end
+
+        it "matches against a hash submitted and received by value" do
+          expect(a_double).to receive(:random_call).with(:a => "a", :b => "b")
+          a_double.random_call(:a => "a", :b => "b")
+        end
+
+        it "matches against a hash submitted by reference and received by value" do
+          opts = {:a => "a", :b => "b"}
+          expect(a_double).to receive(:random_call).with(opts)
+          a_double.random_call(:a => "a", :b => "b")
+        end
+
+        it "matches against a hash submitted by value and received by reference" do
+          opts = {:a => "a", :b => "b"}
+          expect(a_double).to receive(:random_call).with(:a => "a", :b => "b")
+          a_double.random_call(opts)
+        end
+
+        it "fails for a hash w/ wrong values", :reset => true do
+          expect(a_double).to receive(:random_call).with(:a => "b", :c => "d")
+          expect do
+            a_double.random_call(:a => "b", :c => "e")
+          end.to fail_matching(/expected: \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\)/)
+        end
+
+        it "fails for a hash w/ wrong keys", :reset => true do
+          expect(a_double).to receive(:random_call).with(:a => "b", :c => "d")
+          expect do
+            a_double.random_call("a" => "b", "c" => "d")
+          end.to fail_matching(/expected: \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\)/)
+        end
+
+        it "matches a class against itself" do
+          expect(a_double).to receive(:foo).with(Fixnum)
+          a_double.foo(Fixnum)
+        end
+
+        it "fails a class against an unrelated class", :reset => true do
+          expect(a_double).to receive(:foo).with(Fixnum)
+          expect { a_double.foo(Hash) }.to fail
+        end
+
+        it "matches a class against an instance of itself" do
+          expect(a_double).to receive(:foo).with(Fixnum)
+          a_double.foo(3)
+        end
+
+        it "fails a class against an object of a different type", :reset => true do
+          expect(a_double).to receive(:foo).with(Fixnum)
+          expect { a_double.foo(3.2) }.to fail
+        end
+
+        it "fails with zero arguments", :reset => true do
+          expect do
+            expect(a_double).to receive(:msg).with {|arg| expect(arg).to eq :received }
+          end.to raise_error(ArgumentError, /must have at least one argument/)
+        end
+
+        it "fails with sensible message when args respond to #description", :reset => true do
+          arg = double(:description => nil, :inspect => "my_thing")
+
+          expect(a_double).to receive(:msg).with(3)
+          expect { a_double.msg arg }.to fail_matching "got: (my_thing)"
+        end
+
+        it "fails with sensible message when arg#description is nil", :reset => true do
+          arg = double(:description => nil, :inspect => "my_thing")
+
+          expect(a_double).to receive(:msg).with(arg)
+          expect { a_double.msg 3 }.to fail_matching "expected: (my_thing)"
+        end
+
+        it "fails with sensible message when arg#description is blank", :reset => true do
+          arg = double(:description => "", :inspect => "my_thing")
+
+          expect(a_double).to receive(:msg).with(arg)
+          expect { a_double.msg 3 }.to fail_matching "expected: (my_thing)"
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/array_including_matcher_spec.rb b/rspec-mocks/spec/rspec/mocks/array_including_matcher_spec.rb
new file mode 100644
index 0000000..1430f03
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/array_including_matcher_spec.rb
@@ -0,0 +1,62 @@
+module RSpec
+  module Mocks
+    module ArgumentMatchers
+      RSpec.describe ArrayIncludingMatcher do
+        it "describes itself properly" do
+          expect(ArrayIncludingMatcher.new([1, 2, 3]).description).to eq "array_including(1, 2, 3)"
+        end
+
+        it "describes passed matchers" do
+          description = array_including(fake_matcher(Object.new)).description
+
+          expect(description).to include(MatcherHelpers.fake_matcher_description)
+        end
+
+        context "passing" do
+          it "matches the same array" do
+            expect(array_including(1, 2, 3)).to be === [1, 2, 3]
+          end
+
+          it "matches the same array,  specified without square brackets" do
+            expect(array_including(1, 2, 3)).to be === [1, 2, 3]
+          end
+
+          it "matches the same array,  which includes nested arrays" do
+            expect(array_including([1, 2], 3, 4)).to be === [[1, 2], 3, 4]
+          end
+
+          it "works with duplicates in expected" do
+            expect(array_including(1, 1, 2, 3)).to be === [1, 2, 3]
+          end
+
+          it "works with duplicates in actual" do
+            expect(array_including(1, 2, 3)).to be === [1, 1, 2, 3]
+          end
+
+          it "is composable with other matchers" do
+            klass = Class.new
+            dbl = double
+            expect(dbl).to receive(:a_message).with(3, array_including(instance_of(klass)))
+            dbl.a_message(3, [1, klass.new, 4])
+          end
+        end
+
+        context "failing" do
+          it "fails when not all the entries in the expected are present" do
+            expect(array_including(1,2,3,4,5)).not_to be === [1,2]
+          end
+
+          it "fails when passed a composed matcher is pased and not satisfied" do
+            with_unfulfilled_double do |dbl|
+              expect {
+                klass = Class.new
+                expect(dbl).to receive(:a_message).with(3, array_including(instance_of(klass)))
+                dbl.a_message(3, [1, 4])
+              }.to fail_with(/expected: \(3, array_including\(an_instance_of\(\)\)\)/)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/at_least_spec.rb b/rspec-mocks/spec/rspec/mocks/at_least_spec.rb
new file mode 100644
index 0000000..e65dc12
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/at_least_spec.rb
@@ -0,0 +1,147 @@
+module RSpec
+  module Mocks
+    RSpec.describe "at_least" do
+      before(:each) { @double = double }
+
+      it "fails if method is never called" do
+        expect(@double).to receive(:do_something).at_least(4).times
+        expect {
+          verify @double
+        }.to raise_error(/expected: at least 4 times.*received: 0 times/m)
+      end
+
+      it "fails when called less than n times" do
+        expect(@double).to receive(:do_something).at_least(4).times
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        expect {
+          verify @double
+        }.to raise_error(/expected: at least 4 times.*received: 3 times/m)
+      end
+
+      it "fails when at least once method is never called" do
+        expect(@double).to receive(:do_something).at_least(:once)
+        expect {
+          verify @double
+        }.to raise_error(/expected: at least 1 time.*received: 0 times/m)
+      end
+
+      it "fails when at least twice method is called once" do
+        expect(@double).to receive(:do_something).at_least(:twice)
+        @double.do_something
+        expect {
+          verify @double
+        }.to raise_error(/expected: at least 2 times.*received: 1 time/m)
+      end
+
+      it "fails when at least twice method is never called" do
+        expect(@double).to receive(:do_something).at_least(:twice)
+        expect {
+          verify @double
+        }.to raise_error(/expected: at least 2 times.*received: 0 times/m)
+      end
+
+      it "fails when at least thrice method is called less than three times" do
+        expect(@double).to receive(:do_something).at_least(:thrice)
+        @double.do_something
+        @double.do_something
+        expect {
+          verify @double
+        }.to raise_error(/expected: at least 3 times.*received: 2 times/m)
+      end
+
+      it "passes when at least n times method is called exactly n times" do
+        expect(@double).to receive(:do_something).at_least(4).times
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least n times method is called n plus 1 times" do
+        expect(@double).to receive(:do_something).at_least(4).times
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least once method is called once" do
+        expect(@double).to receive(:do_something).at_least(:once)
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least once method is called twice" do
+        expect(@double).to receive(:do_something).at_least(:once)
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least twice method is called three times" do
+        expect(@double).to receive(:do_something).at_least(:twice)
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least twice method is called twice" do
+        expect(@double).to receive(:do_something).at_least(:twice)
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least thrice method is called three times" do
+        expect(@double).to receive(:do_something).at_least(:thrice)
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at least thrice method is called four times" do
+        expect(@double).to receive(:do_something).at_least(:thrice)
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "returns the value given by a block when the at least once method is called" do
+        expect(@double).to receive(:to_s).at_least(:once) { "testing" }
+        expect(@double.to_s).to eq "testing"
+        verify @double
+      end
+
+      context "when sent with 0" do
+        it "outputs a removal message" do
+          expect {
+            expect(@double).to receive(:do_something).at_least(0).times
+          }.to raise_error(/has been removed/)
+        end
+      end
+
+      it "uses a stub value if no value set" do
+        allow(@double).to receive_messages(:do_something => 'foo')
+        expect(@double).to receive(:do_something).at_least(:once)
+        expect(@double.do_something).to eq 'foo'
+        expect(@double.do_something).to eq 'foo'
+      end
+
+      it "prefers its own return value over a stub" do
+        allow(@double).to receive_messages(:do_something => 'foo')
+        expect(@double).to receive(:do_something).at_least(:once).and_return('bar')
+        expect(@double.do_something).to eq 'bar'
+        expect(@double.do_something).to eq 'bar'
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/at_most_spec.rb b/rspec-mocks/spec/rspec/mocks/at_most_spec.rb
new file mode 100644
index 0000000..3442e67
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/at_most_spec.rb
@@ -0,0 +1,113 @@
+module RSpec
+  module Mocks
+    RSpec.describe "at_most" do
+      before(:each) do
+        @double = double
+      end
+
+      it "passes when at_most(n) is called exactly n times" do
+        expect(@double).to receive(:do_something).at_most(2).times
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at_most(n) is called less than n times" do
+        expect(@double).to receive(:do_something).at_most(2).times
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at_most(n) is never called" do
+        expect(@double).to receive(:do_something).at_most(2).times
+        verify @double
+      end
+
+      it "passes when at_most(:once) is called once" do
+        expect(@double).to receive(:do_something).at_most(:once)
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at_most(:once) is never called" do
+        expect(@double).to receive(:do_something).at_most(:once)
+        verify @double
+      end
+
+      it "passes when at_most(:twice) is called once" do
+        expect(@double).to receive(:do_something).at_most(:twice)
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at_most(:twice) is called twice" do
+        expect(@double).to receive(:do_something).at_most(:twice)
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at_most(:twice) is never called" do
+        expect(@double).to receive(:do_something).at_most(:twice)
+        verify @double
+      end
+
+      it "passes when at_most(:thrice) is called less than three times" do
+        expect(@double).to receive(:do_something).at_most(:thrice)
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when at_most(:thrice) is called thrice" do
+        expect(@double).to receive(:do_something).at_most(:thrice)
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "returns the value given by a block when at_most(:once) method is called" do
+        expect(@double).to receive(:to_s).at_most(:once) { "testing" }
+        expect(@double.to_s).to eq "testing"
+        verify @double
+      end
+
+      it "fails fast when at_most(n) times method is called n plus 1 times" do
+        expect(@double).to receive(:do_something).at_most(2).times
+        @double.do_something
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(/expected: at most 2 times.*received: 3 times/m)
+      end
+
+      it "fails fast when at_most(:once) and is called twice" do
+        expect(@double).to receive(:do_something).at_most(:once)
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(/expected: at most 1 time.*received: 2 times/m)
+      end
+
+      it "fails fast when at_most(:twice) and is called three times" do
+        expect(@double).to receive(:do_something).at_most(:twice)
+        @double.do_something
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(/expected: at most 2 times.*received: 3 times/m)
+      end
+
+      it "fails fast when at_most(:thrice) and is called four times" do
+        expect(@double).to receive(:do_something).at_most(:thrice)
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(/expected: at most 3 times.*received: 4 times/m)
+      end
+
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/before_all_spec.rb b/rspec-mocks/spec/rspec/mocks/before_all_spec.rb
new file mode 100644
index 0000000..44ccb97
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/before_all_spec.rb
@@ -0,0 +1,75 @@
+require 'support/before_all_shared_example_group'
+
+RSpec.describe "Using rspec-mocks features in before(:all) blocks" do
+  describe "#stub_const" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        stub_const("SomeNewConst", Class.new)
+      end
+
+      it 'does not stub the const' do
+        expect(defined?(SomeNewConst)).to be_falsey
+      end
+    end
+  end
+
+  describe "#hide_const(for an undefined const)" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        hide_const("Foo")
+      end
+    end
+  end
+
+  describe "#hide_const(for a defined const)" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        hide_const("Float")
+      end
+
+      it 'does not hide the const' do
+        expect(defined?(Float)).to be_truthy
+      end
+    end
+  end
+
+  describe "allow(...).to receive_message_chain" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        allow(Object).to receive_message_chain(:foo, :bar)
+      end
+    end
+  end
+
+  describe "#expect(...).to receive" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        expect(Object).to receive(:foo)
+      end
+    end
+  end
+
+  describe "#allow(...).to receive" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        allow(Object).to receive(:foo)
+      end
+    end
+  end
+
+  describe "#expect_any_instance_of(...).to receive" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        expect_any_instance_of(Object).to receive(:foo)
+      end
+    end
+  end
+
+  describe "#allow_any_instance_of(...).to receive" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        allow_any_instance_of(Object).to receive(:foo)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/block_return_value_spec.rb b/rspec-mocks/spec/rspec/mocks/block_return_value_spec.rb
new file mode 100644
index 0000000..5a16ca1
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/block_return_value_spec.rb
@@ -0,0 +1,68 @@
+RSpec.describe "a double declaration with a block handed to:" do
+  describe "expect(...).to receive" do
+    it "returns the value of executing the block" do
+      obj = Object.new
+      expect(obj).to receive(:foo) { 'bar' }
+      expect(obj.foo).to eq('bar')
+    end
+
+    it "works when a multi-return stub has already been set" do
+      obj = Object.new
+      return_value = Object.new
+      allow(obj).to receive(:foo).and_return(return_value, nil)
+      expect(obj).to receive(:foo) { return_value }
+      expect(obj.foo).to be(return_value)
+    end
+  end
+
+  describe "allow(...).to receive" do
+    it "returns the value of executing the block" do
+      obj = Object.new
+      allow(obj).to receive(:foo) { 'bar' }
+      expect(obj.foo).to eq('bar')
+    end
+
+    # The "receives a block" part is important: 1.8.7 has a bug that reports the
+    # wrong arity when a block receives a block.
+    it 'forwards all given args to the block, even when it receives a block' do
+      obj = Object.new
+      yielded_args = []
+      allow(obj).to receive(:foo) { |*args, &bl| yielded_args << args }
+      obj.foo(1, 2, 3)
+
+      expect(yielded_args).to eq([[1, 2, 3]])
+    end
+  end
+
+  describe "with" do
+    it "returns the value of executing the block" do
+      obj = Object.new
+      allow(obj).to receive(:foo).with('baz') { 'bar' }
+      expect(obj.foo('baz')).to eq('bar')
+    end
+
+    it "returns the value of executing the block with given argument" do
+      obj = Object.new
+      allow(obj).to receive(:foo).with('baz') {|x| 'bar' + x }
+      expect(obj.foo('baz')).to eq('barbaz')
+    end
+  end
+
+  %w[once twice ordered].each do |method|
+    describe method do
+      it "returns the value of executing the block" do
+        obj = Object.new
+        allow(obj).to receive(:foo).send(method) { 'bar' }
+        expect(obj.foo).to eq('bar')
+      end
+    end
+  end
+
+  describe "times" do
+    it "returns the value of executing the block" do
+      obj = Object.new
+      allow(obj).to receive(:foo).at_least(1).times { 'bar' }
+      expect(obj.foo('baz')).to eq('bar')
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/combining_implementation_instructions_spec.rb b/rspec-mocks/spec/rspec/mocks/combining_implementation_instructions_spec.rb
new file mode 100644
index 0000000..3a9b0cb
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/combining_implementation_instructions_spec.rb
@@ -0,0 +1,200 @@
+module RSpec
+  module Mocks
+    RSpec.describe "Combining implementation instructions" do
+      it 'can combine and_yield and and_return' do
+        dbl = double
+        allow(dbl).to receive(:foo).and_yield(5).and_return(3)
+
+        expect { |b|
+          expect(dbl.foo(&b)).to eq(3)
+        }.to yield_with_args(5)
+      end
+
+      describe "combining and_yield, a block implementation and and_return" do
+        def verify_combined_implementation
+          dbl = double
+          (yield dbl).and_yield(5).and_return(3)
+
+          expect { |b|
+            expect(dbl.foo(:arg, &b)).to eq(3)
+          }.to yield_with_args(5)
+
+          expect(@block_called).to be_truthy
+        end
+
+        it 'works when passing a block to `stub`' do
+          verify_combined_implementation do |dbl|
+            allow(dbl).to receive(:foo) { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `with`' do
+          verify_combined_implementation do |dbl|
+            allow(dbl).to receive(:foo).with(:arg) { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `exactly`' do
+          verify_combined_implementation do |dbl|
+            expect(dbl).to receive(:foo).exactly(:once) { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `at_least`' do
+          verify_combined_implementation do |dbl|
+            expect(dbl).to receive(:foo).at_least(:once) { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `at_most`' do
+          verify_combined_implementation do |dbl|
+            expect(dbl).to receive(:foo).at_most(:once) { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `times`' do
+          verify_combined_implementation do |dbl|
+            expect(dbl).to receive(:foo).exactly(1).times { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `once`' do
+          verify_combined_implementation do |dbl|
+            expect(dbl).to receive(:foo).once { @block_called = true }
+          end
+        end
+
+        it 'works when passing a block to `twice`' do
+          the_double = nil
+
+          verify_combined_implementation do |dbl|
+            the_double = dbl
+            expect(dbl).to receive(:foo).twice { @block_called = true }
+          end
+
+          the_double.foo { |a| } # to ensure it is called twice
+        end
+
+        it 'works when passing a block to `ordered`' do
+          verify_combined_implementation do |dbl|
+            expect(dbl).to receive(:foo).ordered { @block_called = true }
+          end
+        end
+      end
+
+      it 'can combine and_yield and and_raise' do
+        dbl = double
+        allow(dbl).to receive(:foo).and_yield(5).and_raise("boom")
+
+        expect { |b|
+          expect { dbl.foo(&b) }.to raise_error("boom")
+        }.to yield_with_args(5)
+      end
+
+      it 'can combine and_yield, a block implementation and and_raise' do
+        dbl = double
+        block_called = false
+        allow(dbl).to receive(:foo) { block_called = true }.and_yield(5).and_raise("boom")
+
+        expect { |b|
+          expect { dbl.foo(&b) }.to raise_error("boom")
+        }.to yield_with_args(5)
+
+        expect(block_called).to be_truthy
+      end
+
+      it 'can combine and_yield and and_throw' do
+        dbl = double
+        allow(dbl).to receive(:foo).and_yield(5).and_throw(:bar)
+
+        expect { |b|
+          expect { dbl.foo(&b) }.to throw_symbol(:bar)
+        }.to yield_with_args(5)
+      end
+
+      it 'can combine and_yield, a block implementation and and_throw' do
+        dbl = double
+        block_called = false
+        allow(dbl).to receive(:foo) { block_called = true }.and_yield(5).and_throw(:bar)
+
+        expect { |b|
+          expect { dbl.foo(&b) }.to throw_symbol(:bar)
+        }.to yield_with_args(5)
+
+        expect(block_called).to be_truthy
+      end
+
+      describe "a double that already has a terminal `and_return(x)` action" do
+        let(:the_dbl) { double }
+        let(:stubbed_double) { allow(the_dbl).to receive(:foo) }
+        before { stubbed_double.and_return(1) }
+
+        it 'allows the terminal action to be overriden to `and_return(y)`' do
+          stubbed_double.and_return(3)
+          expect(the_dbl.foo).to eq(3)
+        end
+
+        it 'allows the terminal action to be overriden to `and_raise(y)`' do
+          stubbed_double.and_raise("boom")
+          expect { the_dbl.foo }.to raise_error("boom")
+        end
+
+        it 'allows the terminal action to be overriden to `and_throw(y)`' do
+          stubbed_double.and_throw(:bar)
+          expect { the_dbl.foo }.to throw_symbol(:bar)
+        end
+      end
+
+      describe "a double that already has a terminal block action" do
+        let(:the_dbl) { double }
+        let(:stubbed_double) { allow(the_dbl).to receive(:foo) }
+
+        it "allows the block action to be overridden" do
+          allow(RSpec).to receive(:warning)
+          stubbed_double.with(:arg) { :with_block }
+          stubbed_double.at_least(:once) { :at_least_block }
+          expect(the_dbl.foo(:arg)).to eq(:at_least_block)
+        end
+      end
+
+      it 'warns when the inner implementation block is overriden' do
+        expect(RSpec).to receive(:warning).with(/overriding a previous stub implementation of `foo`.*#{__FILE__}:#{__LINE__ + 1}/)
+        allow(double).to receive(:foo).with(:arg) { :with_block }.at_least(:once) { :at_least_block }
+      end
+
+      it "does not warn about overriding the stub when `:with` is chained off the block" do
+        expect(RSpec).not_to receive(:warning)
+
+        obj = Object.new
+        stub = allow(obj).to receive(:foo) { }
+        stub.with(1)
+      end
+
+      it 'can combine and_call_original, with, and_return' do
+        obj = Struct.new(:value).new('original')
+        allow(obj).to receive(:value).and_call_original
+        allow(obj).to receive(:value).with(:arg).and_return('value')
+        expect(obj.value).to eq 'original'
+        expect(obj.value(:arg)).to eq 'value'
+      end
+
+      it 'raises an error if `and_call_original` is followed by any other instructions' do
+        allow(RSpec).to receive(:warning)
+        dbl = [1, 2, 3]
+        stubbed = allow(dbl).to receive(:size)
+        stubbed.and_call_original
+
+        msg_fragment = /cannot be modified further/
+
+        expect { stubbed.and_yield }.to raise_error(msg_fragment)
+        expect { stubbed.and_return(1) }.to raise_error(msg_fragment)
+        expect { stubbed.and_raise("a") }.to raise_error(msg_fragment)
+        expect { stubbed.and_throw(:bar) }.to raise_error(msg_fragment)
+
+        expect { stubbed.once { } }.to raise_error(msg_fragment)
+
+        expect(dbl.size).to eq(3)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/configuration_spec.rb b/rspec-mocks/spec/rspec/mocks/configuration_spec.rb
new file mode 100644
index 0000000..3a91cdf
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/configuration_spec.rb
@@ -0,0 +1,189 @@
+module RSpec
+  module Mocks
+    RSpec.describe Configuration do
+      let(:config) { Configuration.new }
+      let(:mod_1)  { Module.new }
+      let(:mod_2)  { Module.new }
+
+      def instance_methods_of(mod)
+        mod_1.instance_methods.map(&:to_sym)
+      end
+
+      it 'adds stub and should_receive to the given modules' do
+        expect(instance_methods_of(mod_1)).not_to include(:stub, :should_receive)
+        expect(instance_methods_of(mod_2)).not_to include(:stub, :should_receive)
+
+        config.add_stub_and_should_receive_to(mod_1, mod_2)
+
+        expect(instance_methods_of(mod_1)).to include(:stub, :should_receive)
+        expect(instance_methods_of(mod_2)).to include(:stub, :should_receive)
+      end
+
+      shared_examples "configuring the syntax" do
+        def sandboxed
+          orig_syntax = RSpec::Mocks.configuration.syntax
+          yield
+        ensure
+          configure_syntax(orig_syntax)
+        end
+
+        around(:each) { |ex| sandboxed(&ex) }
+        let(:dbl) { double }
+        let(:should_methods)       { [:should_receive, :stub, :should_not_receive] }
+        let(:should_class_methods) { [:any_instance] }
+        let(:expect_methods)      { [:receive, :allow, :expect_any_instance_of, :allow_any_instance_of] }
+
+        it 'defaults to enabling both the :should and :expect syntaxes' do
+          # This is kinda a hack, but since we want to enforce use of
+          # the expect syntax within our specs here, we have modified the
+          # config setting, which makes it hard to get at the original
+          # default value. in spec_helper.rb we store the default value
+          # in $default_rspec_mocks_syntax so we can use it here.
+          RSpec::Mocks.configuration.syntax = $default_rspec_mocks_syntax
+          expect(dbl).to respond_to(*should_methods)
+          expect(self).to respond_to(*expect_methods)
+        end
+
+        context 'when configured to :expect' do
+          before { configure_syntax :expect }
+
+          it 'removes the should methods from every object' do
+            expect(dbl).not_to respond_to(*should_methods)
+          end
+
+          it 'removes `any_instance` from every class' do
+            expect(Class.new).not_to respond_to(*should_class_methods)
+          end
+
+          it 'adds the expect methods to the example group context' do
+            expect(self).to respond_to(*expect_methods)
+          end
+
+          it 'reports that the syntax is :expect' do
+            expect(configured_syntax).to eq([:expect])
+          end
+
+          it 'is a no-op when configured a second time' do
+            expect(Syntax.default_should_syntax_host).not_to receive(:method_undefined)
+            expect(::RSpec::Mocks::ExampleMethods).not_to receive(:method_added)
+            configure_syntax :expect
+          end
+        end
+
+        context 'when configured to :should' do
+          before { configure_syntax :should }
+
+          it 'adds the should methods to every object' do
+            expect(dbl).to respond_to(*should_methods)
+          end
+
+          it 'adds `any_instance` to every class' do
+            expect(Class.new).to respond_to(*should_class_methods)
+          end
+
+          it 'removes the expect methods from the example group context' do
+            expect(self).not_to respond_to(*expect_methods)
+          end
+
+          it 'reports that the syntax is :should' do
+            expect(configured_syntax).to eq([:should])
+          end
+
+          it "does not warn about the should syntax" do
+            RSpec.should_not_receive(:deprecate)
+            Object.new.should_not_receive(:bees)
+          end
+
+          it 'is a no-op when configured a second time' do
+            Syntax.default_should_syntax_host.should_not_receive(:method_added)
+            ::RSpec::Mocks::ExampleMethods.should_not_receive(:method_undefined)
+            configure_syntax :should
+          end
+        end
+
+        context 'when configured to [:should, :expect]' do
+          before { configure_syntax [:should, :expect] }
+
+          it 'adds the should methods to every object' do
+            expect(dbl).to respond_to(*should_methods)
+          end
+
+          it 'adds `any_instance` to every class' do
+            expect(Class.new).to respond_to(*should_class_methods)
+          end
+
+          it 'adds the expect methods to the example group context' do
+            expect(self).to respond_to(*expect_methods)
+          end
+
+          it 'reports that both syntaxes are enabled' do
+            expect(configured_syntax).to eq([:should, :expect])
+          end
+
+          it "does not warn about the should syntax" do
+            expect(RSpec).not_to receive(:deprecate)
+            expect(Object.new).not_to receive(:bees)
+          end
+        end
+      end
+
+      describe "configuring rspec-mocks directly" do
+        it_behaves_like "configuring the syntax" do
+          def configure_syntax(syntax)
+            RSpec::Mocks.configuration.syntax = syntax
+          end
+
+          def configured_syntax
+            RSpec::Mocks.configuration.syntax
+          end
+
+          def configure_default_syntax
+            RSpec::Mocks.configuration.reset_syntaxes_to_default
+          end
+        end
+      end
+
+      describe "configuring using the rspec-core config API" do
+        it_behaves_like "configuring the syntax" do
+          def configure_syntax(syntax)
+            RSpec.configure do |rspec|
+              rspec.mock_with :rspec do |c|
+                c.syntax = syntax
+              end
+            end
+          end
+
+          def configured_syntax
+            RSpec.configure do |rspec|
+              rspec.mock_with :rspec do |c|
+                return c.syntax
+              end
+            end
+          end
+
+          def configure_default_syntax
+            RSpec.configure do |rspec|
+              rspec.mock_with :rspec do |c|
+                c.reset_syntaxes_to_default
+              end
+            end
+          end
+        end
+      end
+
+      describe "#when_declaring_verifying_double" do
+        include_context 'with isolated configuration'
+
+        it "captures the supplied blocks" do
+          block = proc { |ref| ref }
+          block2 = proc { |ref| ref }
+          RSpec.configuration.mock_with :rspec do |config|
+            config.when_declaring_verifying_double(&block)
+            config.when_declaring_verifying_double(&block2)
+            expect(config.verifying_double_declaration_callbacks).to eq [block, block2]
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/diffing_spec.rb b/rspec-mocks/spec/rspec/mocks/diffing_spec.rb
new file mode 100644
index 0000000..4fb41c2
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/diffing_spec.rb
@@ -0,0 +1,131 @@
+require "spec_helper"
+require "pp"
+
+RSpec.describe "Diffs printed when arguments don't match" do
+  before do
+    allow(RSpec::Mocks.configuration).to receive(:color?).and_return(false)
+  end
+
+  context "with a non matcher object" do
+    it "does not print a diff when single line arguments are mismatched" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with("some string")
+        expect {
+          d.foo("this other string")
+        }.to fail_with(a_string_excluding("Diff:"))
+      end
+    end
+
+    it "prints a diff of the strings for individual mismatched multi-line string arguments" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with("some string\nline2")
+        expect {
+          d.foo("this other string")
+        }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: (\"some string\\nline2\")\n       got: (\"this other string\")\nDiff:\n@@ -1,3 +1,2 @@\n-some string\n-line2\n+this other string\n")
+      end
+    end
+
+    it "prints a diff of the args lists for multiple mismatched string arguments" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with("some string\nline2", "some other string")
+        expect {
+          d.foo("this other string")
+        }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: (\"some string\\nline2\", \"some other string\")\n       got: (\"this other string\")\nDiff:\n@@ -1,3 +1,2 @@\n-some string\\nline2\n-some other string\n+this other string\n")
+      end
+    end
+
+    it "does not print a diff when multiple single-line string arguments are mismatched" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with("some string", "some other string")
+        expect {
+          d.foo("this other string", "a fourth string")
+        }.to fail_with(a_string_excluding("Diff:"))
+      end
+    end
+
+    let(:expected_hash) { {:foo => :bar, :baz => :quz} }
+
+    let(:actual_hash) { {:bad => :hash} }
+
+    it "prints a diff with hash args" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with(expected_hash)
+        expect {
+          d.foo(:bad => :hash)
+        }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: (#{expected_hash.inspect})\n       got: (#{actual_hash.inspect})\nDiff:\n@@ -1,2 +1,2 @@\n-[#{expected_hash.inspect}]\n+[#{actual_hash.inspect}]\n")
+      end
+    end
+
+    it "prints a diff with an expected hash arg and a non-hash actual arg" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with(expected_hash)
+        expect {
+          d.foo(Object.new)
+        }.to fail_with(/-\[#{Regexp.escape(expected_hash.inspect)}\].*\+\[#<Object.*>\]/m)
+      end
+    end
+
+    it "prints a diff with array args" do
+      with_unfulfilled_double do |d|
+        expect(d).to receive(:foo).with([:a, :b, :c])
+        expect {
+          d.foo([])
+        }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: ([:a, :b, :c])\n       got: ([])\nDiff:\n@@ -1,2 +1,2 @@\n-[[:a, :b, :c]]\n+[[]]\n")
+      end
+    end
+
+    context "that defines #description" do
+      it "does not use the object's description for a non-matcher object that implements #description" do
+        with_unfulfilled_double do |d|
+
+          collab = double(:collab, :description => "This string")
+          collab_inspect = collab.inspect
+
+          expect(d).to receive(:foo).with(collab)
+          expect {
+            d.foo([])
+          }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: (#{collab_inspect})\n       got: ([])\nDiff:\n@@ -1,2 +1,2 @@\n-[#{collab_inspect}]\n+[[]]\n")
+        end
+      end
+    end
+  end
+
+  context "with a matcher object" do
+    context "that defines #description" do
+      it "uses the object's description" do
+        with_unfulfilled_double do |d|
+
+          collab = fake_matcher(Object.new)
+          collab_description = collab.description
+
+          expect(d).to receive(:foo).with(collab)
+          expect {
+            d.foo([:a, :b])
+          }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: (#{collab_description})\n       got: ([:a, :b])\nDiff:\n@@ -1,2 +1,2 @@\n-[\"#{collab_description}\"]\n+[[:a, :b]]\n")
+        end
+      end
+    end
+
+    context "that does not define #description" do
+      it "for a matcher object that does not implement #description" do
+        with_unfulfilled_double do |d|
+          collab = Class.new do
+            def self.name
+              "RSpec::Mocks::ArgumentMatchers::"
+            end
+          end.new
+
+          expect(RSpec::Support.is_a_matcher?(collab)).to be true
+
+          collab_inspect = collab.inspect
+          collab_pp = PP.pp(collab, "").strip
+
+          expect(d).to receive(:foo).with(collab)
+          expect {
+            d.foo([:a, :b])
+          }.to fail_with("Double \"double\" received :foo with unexpected arguments\n  expected: (#{collab_inspect})\n       got: ([:a, :b])\nDiff:\n@@ -1,2 +1,2 @@\n-[#{collab_pp}]\n+[[:a, :b]]\n")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/double_spec.rb b/rspec-mocks/spec/rspec/mocks/double_spec.rb
new file mode 100644
index 0000000..4dac642
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/double_spec.rb
@@ -0,0 +1,830 @@
+module RSpec
+  module Mocks
+    RSpec.describe Double do
+      before(:each) { @double = double("test double") }
+      after(:each)  { reset @double }
+
+      it "has method_missing as private" do
+        expect(RSpec::Mocks::Double.private_instance_methods).to include_method(:method_missing)
+      end
+
+      it "does not respond_to? method_missing (because it's private)" do
+        expect(RSpec::Mocks::Double.new).not_to respond_to(:method_missing)
+      end
+
+      it "uses 'Double' in failure messages" do
+        dbl = double('name')
+        expect { dbl.foo }.to raise_error(/Double "name" received/)
+      end
+
+      it "hides internals in its inspect representation" do
+        m = double('cup')
+        expect(m.inspect).to match(/#<RSpec::Mocks::Double:0x[a-f0-9.]+ @name="cup">/)
+      end
+
+      it 'does not blow up when resetting standard object methods' do
+        dbl = double(:tainted? => true)
+        expect(dbl.tainted?).to eq(true)
+        expect { reset dbl }.not_to raise_error
+      end
+
+      it 'does not get string vs symbol messages confused' do
+        dbl = double("foo" => 1)
+        allow(dbl).to receive(:foo).and_return(2)
+        expect(dbl.foo).to eq(2)
+        expect { reset dbl }.not_to raise_error
+      end
+
+      it "generates the correct error when an unfulfilled expectation uses an unused double as a `with` argument" do
+        expect {
+          a = double('a')
+          b = double('b')
+          expect(a).to receive(:append).with(b)
+          verify_all
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it 'allows string representation of methods in constructor' do
+        dbl = double('foo' => 1)
+        expect(dbl.foo).to eq(1)
+      end
+
+      it 'allows setter methods to be stubbed' do
+        dbl = double('foo=' => 1)
+
+        # Note the specified return value is thrown away. This is a Ruby semantics
+        # thing. You cannot change the return value of assignment.
+        expect(dbl.foo = "bar").to eq("bar")
+      end
+
+      it 'allows `class` to be stubbed even when `any_instance` has already been used' do
+        # See https://github.com/rspec/rspec-mocks/issues/687
+        # The infinite recursion code path was only triggered when there were
+        # active any instance recorders in the current example, so we make one here.
+        allow_any_instance_of(Object).to receive(:bar).and_return(2)
+
+        dbl = double(:foo => 1, :class => String)
+        expect(dbl.foo).to eq(1)
+        expect(dbl.class).to eq(String)
+      end
+
+      it 'allows `send` to be stubbed' do
+        dbl = double
+        allow(dbl).to receive(:send).and_return("received")
+        expect(dbl.send(:some_msg)).to eq("received")
+      end
+
+      it "reports line number of expectation of unreceived message" do
+        expected_error_line = __LINE__; expect(@double).to receive(:wont_happen).with("x", 3)
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError) { |e|
+          # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line
+          expect(e.backtrace[0]).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
+        }
+      end
+
+      it "reports line number of expectation of unreceived message after a message expecation after similar stub" do
+        allow(@double).to receive(:wont_happen)
+        expected_error_line = __LINE__; expect(@double).to receive(:wont_happen).with("x", 3)
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError) { |e|
+          # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line
+          expect(e.backtrace[0]).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
+        }
+      end
+
+      it "passes when not receiving message specified as not to be received" do
+        expect(@double).not_to receive(:not_expected)
+        verify @double
+      end
+
+      it "prevents confusing double-negative expressions involving `never`" do
+        expect {
+          expect(@double).not_to receive(:not_expected).never
+        }.to raise_error(/trying to negate it again/)
+      end
+
+      it "warns when `and_return` is called on a negative expectation" do
+        expect {
+          expect(@double).not_to receive(:do_something).and_return(1)
+        }.to raise_error(/not supported/)
+
+        expect {
+          expect(@double).not_to receive(:do_something).and_return(1)
+        }.to raise_error(/not supported/)
+
+        expect {
+          expect(@double).to receive(:do_something).never.and_return(1)
+        }.to raise_error(/not supported/)
+      end
+
+      it "passes when receiving message specified as not to be received with different args" do
+        expect(@double).not_to receive(:message).with("unwanted text")
+        expect(@double).to receive(:message).with("other text")
+        @double.message "other text"
+        verify @double
+      end
+
+      it "fails when receiving message specified as not to be received" do
+        expect(@double).not_to receive(:not_expected)
+        expect {
+          @double.not_expected
+        }.to raise_error(
+          RSpec::Mocks::MockExpectationError,
+          %Q|(Double "test double").not_expected(no args)\n    expected: 0 times with any arguments\n    received: 1 time|
+        )
+      end
+
+      it "fails when receiving message specified as not to be received with args" do
+        expect(@double).not_to receive(:not_expected).with("unexpected text")
+        expect {
+          @double.not_expected("unexpected text")
+        }.to raise_error(
+          RSpec::Mocks::MockExpectationError,
+          %Q|(Double "test double").not_expected("unexpected text")\n    expected: 0 times with arguments: ("unexpected text")\n    received: 1 time with arguments: ("unexpected text")|
+        )
+      end
+
+      it "fails when array arguments do not match" do
+        expect(@double).not_to receive(:not_expected).with(["do not want"])
+        expect {
+          @double.not_expected(["do not want"])
+        }.to raise_error(
+          RSpec::Mocks::MockExpectationError,
+          %Q|(Double "test double").not_expected(["do not want"])\n    expected: 0 times with arguments: (["do not want"])\n    received: 1 time with arguments: (["do not want"])|
+        )
+      end
+
+      context "when specifying a message should not be received with specific args" do
+        context "using `expect(...).not_to receive()`" do
+          it 'passes when receiving the message with different args' do
+            expect(@double).not_to receive(:not_expected).with("unexpected text")
+            @double.not_expected "really unexpected text"
+            verify @double
+          end
+        end
+
+        context "using `expect(...).to receive().never`" do
+          it 'passes when receiving the message with different args' do
+            expect(@double).to receive(:not_expected).with("unexpected text").never
+            @double.not_expected "really unexpected text"
+            verify @double
+          end
+        end
+      end
+
+      it 'does not get confused when a negative expecation is used with a string and symbol message' do
+        allow(@double).to receive(:foo) { 3 }
+        expect(@double).not_to receive(:foo).with(1)
+        expect(@double).not_to receive("foo").with(2)
+
+        expect(@double.foo).to eq(3)
+        verify @double
+      end
+
+      it 'does not get confused when a positive expectation is used with a string and symbol message' do
+        expect(@double).to receive(:foo).with(1)
+        expect(@double).to receive("foo").with(2)
+
+        @double.foo(1)
+        @double.foo(2)
+
+        verify @double
+      end
+
+      it "allows parameter as return value" do
+        expect(@double).to receive(:something).with("a","b","c").and_return("booh")
+        expect(@double.something("a","b","c")).to eq "booh"
+        verify @double
+      end
+
+      it "returns the previously stubbed value if no return value is set" do
+        allow(@double).to receive(:something).with("a","b","c").and_return(:stubbed_value)
+        expect(@double).to receive(:something).with("a","b","c")
+        expect(@double.something("a","b","c")).to eq :stubbed_value
+        verify @double
+      end
+
+      it "returns nil if no return value is set and there is no previously stubbed value" do
+        expect(@double).to receive(:something).with("a","b","c")
+        expect(@double.something("a","b","c")).to be_nil
+        verify @double
+      end
+
+      it "raises exception if args don't match when method called" do
+        expect(@double).to receive(:something).with("a","b","c").and_return("booh")
+        expect {
+          @double.something("a","d","c")
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n  expected: (\"a\", \"b\", \"c\")\n       got: (\"a\", \"d\", \"c\")")
+      end
+
+      describe "even when a similar expectation with different arguments exist" do
+        it "raises exception if args don't match when method called, correctly reporting the offending arguments" do
+          expect(@double).to receive(:something).with("a","b","c").once
+          expect(@double).to receive(:something).with("z","x","c").once
+          expect {
+            @double.something("a","b","c")
+            @double.something("z","x","g")
+          }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n  expected: (\"z\", \"x\", \"c\")\n       got: (\"z\", \"x\", \"g\")")
+        end
+      end
+
+      it "raises exception if args don't match when method called even when the method is stubbed" do
+        allow(@double).to receive(:something)
+        expect(@double).to receive(:something).with("a","b","c")
+        expect {
+          @double.something("a","d","c")
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n  expected: (\"a\", \"b\", \"c\")\n       got: (\"a\", \"d\", \"c\")")
+      end
+
+      it "raises exception if args don't match when method called even when using null_object" do
+        @double = double("test double").as_null_object
+        expect(@double).to receive(:something).with("a","b","c")
+        expect {
+          @double.something("a","d","c")
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n  expected: (\"a\", \"b\", \"c\")\n       got: (\"a\", \"d\", \"c\")")
+      end
+
+      describe 'with a method that has a default argument' do
+        it "raises an exception if the arguments don't match when the method is called, correctly reporting the offending arguments" do
+          def @double.method_with_default_argument(arg={}); end
+          expect(@double).to receive(:method_with_default_argument).with({})
+
+          expect {
+            @double.method_with_default_argument(nil)
+            verify @double
+          }.to raise_error(RSpec::Mocks::MockExpectationError, a_string_starting_with("Double \"test double\" received :method_with_default_argument with unexpected arguments\n  expected: ({})\n       got: (nil)"))
+        end
+      end
+
+      it "fails if unexpected method called" do
+        expect {
+          @double.something("a","b","c")
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received unexpected message :something with (\"a\", \"b\", \"c\")")
+      end
+
+      it "uses block for expectation if provided" do
+        expect(@double).to receive(:something) do | a, b |
+          expect(a).to eq "a"
+          expect(b).to eq "b"
+          "booh"
+        end
+        expect(@double.something("a", "b")).to eq "booh"
+        verify @double
+      end
+
+      it "fails if expectation block fails" do
+        expect(@double).to receive(:something) do |bool|
+          expect(bool).to be_truthy
+        end
+
+        expect {
+          @double.something false
+        }.to raise_error(RSpec::Expectations::ExpectationNotMetError)
+      end
+
+      it "is wrappable in an array" do
+        with_isolated_stderr do
+          expect( Array(@double) ).to eq([@double])
+        end
+      end
+
+      it "is wrappable in an array when a null object" do
+        with_isolated_stderr do
+          expect( Array(@double.as_null_object) ).to eq [@double]
+        end
+      end
+
+      it "responds to to_ary as a null object" do
+        expect(@double.as_null_object.to_ary).to eq nil
+      end
+
+      it "responds to to_a as a null object" do
+        if RUBY_VERSION.to_f > 1.8
+          expect(@double.as_null_object.to_a).to eq nil
+        else
+          with_isolated_stderr do
+            expect(@double.as_null_object.to_a).to eq [@double]
+          end
+        end
+      end
+
+      it "passes proc to expectation block without an argument" do
+        expect(@double).to receive(:foo) { |&block| expect(block.call).to eq(:bar) }
+        @double.foo { :bar }
+      end
+
+      it "passes proc to expectation block with an argument" do
+        expect(@double).to receive(:foo) { |arg, &block| expect(block.call).to eq(:bar) }
+        @double.foo(:arg) { :bar }
+      end
+
+      it "passes proc to stub block without an argurment" do
+        allow(@double).to receive(:foo) { |&block| expect(block.call).to eq(:bar) }
+        @double.foo { :bar }
+      end
+
+      it "passes proc to stub block with an argument" do
+        allow(@double).to receive(:foo) { |arg, &block| expect(block.call).to eq(:bar) }
+        @double.foo(:arg) { :bar }
+      end
+
+      it "fails right away when method defined as never is received" do
+        expect(@double).to receive(:not_expected).never
+        expect { @double.not_expected }.
+          to raise_error(RSpec::Mocks::MockExpectationError,
+                         %Q|(Double "test double").not_expected(no args)\n    expected: 0 times with any arguments\n    received: 1 time|
+        )
+      end
+
+      it "raises RuntimeError by default" do
+        expect(@double).to receive(:something).and_raise
+        expect { @double.something }.to raise_error(RuntimeError)
+      end
+
+      it "raises RuntimeError with a message by default" do
+        expect(@double).to receive(:something).and_raise("error message")
+        expect { @double.something }.to raise_error(RuntimeError, "error message")
+      end
+
+      it "raises an exception of a given type without an error message" do
+        expect(@double).to receive(:something).and_raise(StandardError)
+        expect { @double.something }.to raise_error(StandardError)
+      end
+
+      it "raises an exception of a given type with a message" do
+        expect(@double).to receive(:something).and_raise(RuntimeError, "error message")
+        expect { @double.something }.to raise_error(RuntimeError, "error message")
+      end
+
+      it "raises a given instance of an exception" do
+        expect(@double).to receive(:something).and_raise(RuntimeError.new("error message"))
+        expect { @double.something }.to raise_error(RuntimeError, "error message")
+      end
+
+      class OutOfGas < StandardError
+        attr_reader :amount, :units
+        def initialize(amount, units)
+          @amount = amount
+          @units  = units
+        end
+      end
+
+      it "raises a given instance of an exception with arguments other than the standard 'message'" do
+        expect(@double).to receive(:something).and_raise(OutOfGas.new(2, :oz))
+
+        expect {
+          @double.something
+        }.to raise_error(OutOfGas) { |e|
+          expect(e.amount).to eq 2
+          expect(e.units).to eq :oz
+        }
+      end
+
+      it "does not raise when told to if args dont match" do
+        expect(@double).to receive(:something).with(2).and_raise(RuntimeError)
+        expect {
+          @double.something 1
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "throws when told to" do
+        expect(@double).to receive(:something).and_throw(:blech)
+        expect {
+          @double.something
+        }.to throw_symbol(:blech)
+      end
+
+      it "ignores args on any args" do
+        expect(@double).to receive(:something).at_least(:once).with(any_args)
+        @double.something
+        @double.something 1
+        @double.something "a", 2
+        @double.something [], {}, "joe", 7
+        verify @double
+      end
+
+      it "fails on no args if any args received" do
+        expect(@double).to receive(:something).with(no_args())
+        expect {
+          @double.something 1
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n  expected: (no args)\n       got: (1)")
+      end
+
+      it "fails when args are expected but none are received" do
+        expect(@double).to receive(:something).with(1)
+        expect {
+          @double.something
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :something with unexpected arguments\n  expected: (1)\n       got: (no args)")
+      end
+
+      it "returns value from block by default" do
+        allow(@double).to receive(:method_that_yields).and_yield
+        value = @double.method_that_yields { :returned_obj }
+        expect(value).to eq :returned_obj
+        verify @double
+      end
+
+      it "yields 0 args to blocks that take a variable number of arguments" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield
+        a = nil
+        @double.yield_back {|*x| a = x}
+        expect(a).to eq []
+        verify @double
+      end
+
+      it "yields 0 args multiple times to blocks that take a variable number of arguments" do
+        expect(@double).to receive(:yield_back).once.with(no_args()).once.and_yield.
+                                                                    and_yield
+        b = []
+        @double.yield_back {|*a| b << a}
+        expect(b).to eq [ [], [] ]
+        verify @double
+      end
+
+      it "yields one arg to blocks that take a variable number of arguments" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield(99)
+        a = nil
+        @double.yield_back {|*x| a = x}
+        expect(a).to eq [99]
+        verify @double
+      end
+
+      it "yields one arg 3 times consecutively to blocks that take a variable number of arguments" do
+        expect(@double).to receive(:yield_back).once.with(no_args()).once.and_yield(99).
+                                                                    and_yield(43).
+                                                                    and_yield("something fruity")
+        b = []
+        @double.yield_back {|*a| b << a}
+        expect(b).to eq [[99], [43], ["something fruity"]]
+        verify @double
+      end
+
+      it "yields many args to blocks that take a variable number of arguments" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go")
+        a = nil
+        @double.yield_back {|*x| a = x}
+        expect(a).to eq [99, 27, "go"]
+        verify @double
+      end
+
+      it "yields many args 3 times consecutively to blocks that take a variable number of arguments" do
+        expect(@double).to receive(:yield_back).once.with(no_args()).once.and_yield(99, :green, "go").
+                                                                    and_yield("wait", :amber).
+                                                                    and_yield("stop", 12, :red)
+        b = []
+        @double.yield_back {|*a| b << a}
+        expect(b).to eq [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]]
+        verify @double
+      end
+
+      it "yields single value" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield(99)
+        a = nil
+        @double.yield_back {|x| a = x}
+        expect(a).to eq 99
+        verify @double
+      end
+
+      it "yields single value 3 times consecutively" do
+        expect(@double).to receive(:yield_back).once.with(no_args()).once.and_yield(99).
+                                                                    and_yield(43).
+                                                                    and_yield("something fruity")
+        b = []
+        @double.yield_back {|a| b << a}
+        expect(b).to eq [99, 43, "something fruity"]
+        verify @double
+      end
+
+      it "yields two values" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
+        a, b = nil
+        @double.yield_back {|x,y| a=x; b=y}
+        expect(a).to eq 'wha'
+        expect(b).to eq 'zup'
+        verify @double
+      end
+
+      it "yields two values 3 times consecutively" do
+        expect(@double).to receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
+                                                                    and_yield('not', 'down').
+                                                                    and_yield(14, 65)
+        c = []
+        @double.yield_back {|a,b| c << [a, b]}
+        expect(c).to eq [['wha', 'zup'], ['not', 'down'], [14, 65]]
+        verify @double
+      end
+
+      it "fails when calling yielding method with wrong arity" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
+        expect {
+          @double.yield_back {|a|}
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" yielded |\"wha\", \"zup\"| to block with arity of 1")
+      end
+
+      if kw_args_supported?
+        it 'fails when calling yielding method with invalid kw args' do
+          expect(@double).to receive(:yield_back).and_yield(:x => 1, :y => 2)
+          expect {
+            eval("@double.yield_back { |x: 1| }")
+          }.to raise_error(RSpec::Mocks::MockExpectationError,
+                           'Double "test double" yielded |{:x=>1, :y=>2}| to block with optional keyword args (:x)')
+        end
+      end
+
+      it "fails when calling yielding method consecutively with wrong arity" do
+        expect(@double).to receive(:yield_back).once.with(no_args()).and_yield('wha', 'zup').
+                                                                     and_yield('down').
+                                                                     and_yield(14, 65)
+        expect {
+          c = []
+          @double.yield_back {|a,b| c << [a, b]}
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" yielded |\"down\"| to block with arity of 2")
+      end
+
+      it "fails when calling yielding method without block" do
+        expect(@double).to receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
+        expect {
+          @double.yield_back
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" asked to yield |[\"wha\", \"zup\"]| but no block was passed")
+      end
+
+      it "is able to double send" do
+        expect(@double).to receive(:send).with(any_args)
+        @double.send 'hi'
+        verify @double
+      end
+
+      it "is able to raise from method calling yielding double" do
+        expect(@double).to receive(:yield_me).and_yield 44
+
+        expect {
+          @double.yield_me do |x|
+            raise "Bang"
+          end
+        }.to raise_error(StandardError, "Bang")
+
+        verify @double
+      end
+
+      it "clears expectations after verify" do
+        expect(@double).to receive(:foobar)
+        @double.foobar
+        verify @double
+        expect {
+          @double.foobar
+        }.to raise_error(RSpec::Mocks::MockExpectationError, %q|Double "test double" received unexpected message :foobar with (no args)|)
+      end
+
+      it "restores objects to their original state on rspec_reset" do
+        double = double("this is a double")
+        expect(double).to receive(:blah)
+        reset double
+        verify double #should throw if reset didn't work
+      end
+
+      it "temporarily replaces a method stub on a double" do
+        allow(@double).to receive(:msg).and_return(:stub_value)
+        expect(@double).to receive(:msg).with(:arg).and_return(:double_value)
+        expect(@double.msg(:arg)).to equal(:double_value)
+        expect(@double.msg).to equal(:stub_value)
+        expect(@double.msg).to equal(:stub_value)
+        verify @double
+      end
+
+      it "does not require a different signature to replace a method stub" do
+        allow(@double).to receive(:msg).and_return(:stub_value)
+        expect(@double).to receive(:msg).and_return(:double_value)
+        expect(@double.msg(:arg)).to equal(:double_value)
+        expect(@double.msg).to equal(:stub_value)
+        expect(@double.msg).to equal(:stub_value)
+        verify @double
+      end
+
+      it "raises an error when a previously stubbed method has a negative expectation" do
+        allow(@double).to receive(:msg).and_return(:stub_value)
+        expect(@double).not_to receive(:msg)
+        expect { @double.msg(:arg) }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "temporarily replaces a method stub on a non-double" do
+        non_double = Object.new
+        allow(non_double).to receive(:msg).and_return(:stub_value)
+        expect(non_double).to receive(:msg).with(:arg).and_return(:double_value)
+        expect(non_double.msg(:arg)).to equal(:double_value)
+        expect(non_double.msg).to equal(:stub_value)
+        expect(non_double.msg).to equal(:stub_value)
+        verify non_double
+      end
+
+      it "returns the stubbed value when no new value specified" do
+        allow(@double).to receive(:msg).and_return(:stub_value)
+        expect(@double).to receive(:msg)
+        expect(@double.msg).to equal(:stub_value)
+        verify @double
+      end
+
+      it "returns the stubbed value when stubbed with args and no new value specified" do
+        allow(@double).to receive(:msg).with(:arg).and_return(:stub_value)
+        expect(@double).to receive(:msg).with(:arg)
+        expect(@double.msg(:arg)).to equal(:stub_value)
+        verify @double
+      end
+
+      it "does not mess with the stub's yielded values when also doubleed" do
+        allow(@double).to receive(:yield_back).and_yield(:stub_value)
+        expect(@double).to receive(:yield_back).and_yield(:double_value)
+        @double.yield_back{|v| expect(v).to eq :double_value }
+        @double.yield_back{|v| expect(v).to eq :stub_value }
+        verify @double
+      end
+
+      it "can yield multiple times when told to do so" do
+        allow(@double).to receive(:foo).and_yield(:stub_value)
+        expect(@double).to receive(:foo).and_yield(:first_yield).and_yield(:second_yield)
+
+        expect { |b| @double.foo(&b) }.to yield_successive_args(:first_yield, :second_yield)
+        expect { |b| @double.foo(&b) }.to yield_with_args(:stub_value)
+
+        verify @double
+      end
+
+      it "assigns stub return values" do
+        double = RSpec::Mocks::Double.new('name', :message => :response)
+        expect(double.message).to eq :response
+      end
+
+      describe "a double message receiving a block" do
+        before(:each) do
+          @double = double("double")
+          @calls = 0
+        end
+
+        def add_call
+          @calls = @calls + 1
+        end
+
+        it "supports a block passed to `receive` for `expect`" do
+          expect(@double).to receive(:foo) { add_call }
+
+          @double.foo
+
+          expect(@calls).to eq 1
+        end
+
+        it "supports a block passed to `receive` for `expect` after a similar stub" do
+          allow(@double).to receive(:foo).and_return(:bar)
+          expect(@double).to receive(:foo) { add_call }
+
+          @double.foo
+
+          expect(@calls).to eq 1
+        end
+
+        it "calls the block after #once" do
+          expect(@double).to receive(:foo).once { add_call }
+
+          @double.foo
+
+          expect(@calls).to eq 1
+        end
+
+        it "calls the block after #twice" do
+          expect(@double).to receive(:foo).twice { add_call }
+
+          @double.foo
+          @double.foo
+
+          expect(@calls).to eq 2
+        end
+
+        it "calls the block after #times" do
+          expect(@double).to receive(:foo).exactly(10).times { add_call }
+
+          (1..10).each { @double.foo }
+
+          expect(@calls).to eq 10
+        end
+
+        it "calls the block after #ordered" do
+          expect(@double).to receive(:foo).ordered { add_call }
+          expect(@double).to receive(:bar).ordered { add_call }
+
+          @double.foo
+          @double.bar
+
+          expect(@calls).to eq 2
+        end
+      end
+
+      describe 'string representation generated by #to_s' do
+        it 'does not contain < because that might lead to invalid HTML in some situations' do
+          double = double("Dog")
+          valid_html_str = "#{double}"
+          expect(valid_html_str).not_to include('<')
+        end
+      end
+
+      describe "#to_str", :unless => RUBY_VERSION == '1.9.2' do
+        it "should not respond to #to_str to avoid being coerced to strings by the runtime" do
+          double = double("Foo")
+          expect { double.to_str }.to raise_error(
+            RSpec::Mocks::MockExpectationError,
+            'Double "Foo" received unexpected message :to_str with (no args)')
+        end
+      end
+
+      describe "double created with no name" do
+        it "does not use a name in a failure message" do
+          double = double()
+          expect {double.foo}.to raise_error(/Double received/)
+        end
+
+        it "does respond to initially stubbed methods" do
+          double = double(:foo => "woo", :bar => "car")
+          expect(double.foo).to eq "woo"
+          expect(double.bar).to eq "car"
+        end
+      end
+
+      describe "==" do
+        it "sends '== self' to the comparison object" do
+          first = double('first')
+          second = double('second')
+
+          expect(first).to receive(:==).with(second)
+          second == first
+        end
+      end
+
+      describe "with" do
+        before { @double = double('double') }
+        context "with args" do
+          context "with matching args" do
+            it "passes" do
+              expect(@double).to receive(:foo).with('bar')
+              @double.foo('bar')
+            end
+          end
+
+          context "with non-matching args" do
+            it "fails" do
+              expect(@double).to receive(:foo).with('bar')
+              expect do
+                @double.foo('baz')
+              end.to raise_error
+              reset @double
+            end
+          end
+
+          context "with non-matching doubles" do
+            it "fails" do
+              d1 = double('1')
+              d2 = double('2')
+              expect(@double).to receive(:foo).with(d1)
+              expect do
+                @double.foo(d2)
+              end.to raise_error
+              reset @double
+            end
+          end
+
+          context "with non-matching doubles as_null_object" do
+            it "fails" do
+              d1 = double('1').as_null_object
+              d2 = double('2').as_null_object
+              expect(@double).to receive(:foo).with(d1)
+              expect do
+                @double.foo(d2)
+              end.to raise_error
+              reset @double
+            end
+          end
+        end
+
+        context "with a block" do
+          context "with matching args" do
+            it "returns the result of the block" do
+              expect(@double).to receive(:foo).with('bar') { 'baz' }
+              expect(@double.foo('bar')).to eq('baz')
+            end
+          end
+
+          context "with non-matching args" do
+            it "fails" do
+              expect(@double).to receive(:foo).with('bar') { 'baz' }
+              expect do
+                expect(@double.foo('wrong')).to eq('baz')
+              end.to raise_error(/received :foo with unexpected arguments/)
+              reset @double
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/error_generator_spec.rb b/rspec-mocks/spec/rspec/mocks/error_generator_spec.rb
new file mode 100644
index 0000000..07c7125
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/error_generator_spec.rb
@@ -0,0 +1,59 @@
+require "spec_helper"
+
+module RSpec
+  module Mocks
+    RSpec.describe ErrorGenerator do
+      def unexpected_failure_message_for(object_description)
+        /received unexpected message :bees with \(#{object_description}\)/
+      end
+
+      describe "formatting arguments" do
+        context "on non-matcher objects that define #description" do
+          it "does not use the object's description" do
+            o = double(:double, :description => "Friends")
+            expect {
+              o.bees(o)
+            }.to fail_with(unexpected_failure_message_for(o.inspect))
+          end
+        end
+
+        context "on matcher objects" do
+          context "that define description" do
+            it "uses the object's description" do
+              d = double(:double)
+              o = fake_matcher(Object.new)
+              expect {
+                d.bees(o)
+              }.to raise_error(unexpected_failure_message_for(o.description))
+            end
+          end
+
+          context "that do not define description" do
+            it "does not use the object's description" do
+              d = double(:double)
+              o = Class.new do
+                def self.name
+                  "RSpec::Mocks::ArgumentMatchers::"
+                end
+              end.new
+
+              expect(RSpec::Support.is_a_matcher?(o)).to be true
+
+              expect {
+                d.bees(o)
+              }.to fail_with(unexpected_failure_message_for(o.inspect))
+            end
+          end
+
+          context "on default method stub" do
+            it "error message display starts in new line" do
+              d = double(:double)
+              allow(d).to receive(:foo).with({})
+              expect { d.foo([]) }.to fail_with(/\nDiff/)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/example_methods_spec.rb b/rspec-mocks/spec/rspec/mocks/example_methods_spec.rb
new file mode 100644
index 0000000..59c5265
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/example_methods_spec.rb
@@ -0,0 +1,38 @@
+module RSpec
+  module Mocks
+    RSpec.describe ExampleMethods do
+      it 'does not define private helper methods since it gets included into a ' +
+         'namespace where users define methods and could inadvertently overwrite ' +
+         'them' do
+        expect(ExampleMethods.private_instance_methods).to eq([])
+      end
+
+      def test_extend_on_new_object(*to_extend, &block)
+        host = Object.new
+        to_extend.each { |mod| host.extend mod }
+        host.instance_eval do
+          dbl = double
+          expect(dbl).to receive(:foo).at_least(:once).and_return(1)
+          dbl.foo
+          instance_exec(dbl, &block) if block
+        end
+      end
+
+      it 'works properly when extended onto an object' do
+        test_extend_on_new_object ExampleMethods
+      end
+
+      it 'works properly when extended onto an object that has previous extended `RSpec::Matchers`' do
+        test_extend_on_new_object RSpec::Matchers, ExampleMethods do |dbl|
+          expect(dbl.foo).to eq(1)
+        end
+      end
+
+      it 'works properly when extended onto an object that later extends `RSpec::Matchers`' do
+        test_extend_on_new_object ExampleMethods, RSpec::Matchers do |dbl|
+          expect(dbl.foo).to eq(1)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/expiration_spec.rb b/rspec-mocks/spec/rspec/mocks/expiration_spec.rb
new file mode 100644
index 0000000..d6d3b37
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/expiration_spec.rb
@@ -0,0 +1,90 @@
+module RSpec
+  module Mocks
+    RSpec.describe "After a test double has been torn down" do
+      RSpec.shared_examples_for "expiration" do
+        before do
+          expect(dbl).to receive(:foo).at_least(:once)
+          allow(dbl).to receive(:bar)
+          dbl.foo
+
+          RSpec::Mocks.verify
+          RSpec::Mocks.teardown
+          RSpec::Mocks.setup
+        end
+
+        it 'disallows previously mocked methods' do
+          expect { dbl.foo }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows previously stubbed methods' do
+          expect { dbl.bar }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows stubbing new methods (with receive)' do
+          expect {
+            allow(dbl).to receive(:bazz)
+          }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows stubbing new methods (with receive_messages)' do
+          expect {
+            allow(dbl).to receive_messages(:bazz => 3)
+          }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows stubbing new message chains' do
+          expect {
+            allow(dbl).to receive_message_chain(:bazz, :bam, :goo)
+          }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows mocking new methods' do
+          expect {
+            expect(dbl).to receive(:bazz)
+          }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows being turned into a null object' do
+          expect { dbl.as_null_object }.to raise_error(ExpiredTestDoubleError)
+        end
+
+        it 'disallows being checked for nullness' do
+          expect { dbl.null_object? }.to raise_error(ExpiredTestDoubleError)
+        end
+
+      end
+
+      context "for a plain double" do
+        let(:dbl) { double }
+        include_examples "expiration"
+      end
+
+      class ExpiredInstanceInterface
+        def foo;  end
+        def bar;  end
+        def bazz; end
+      end
+
+      class ExpiredClassInterface
+        def self.foo;  end
+        def self.bar;  end
+        def self.bazz; end
+      end
+
+      context "for an instance_double" do
+        let(:dbl) { instance_double(ExpiredInstanceInterface) }
+        include_examples "expiration"
+      end
+
+      context "for a class_double" do
+        let(:dbl) { class_double(ExpiredClassInterface) }
+        include_examples "expiration"
+      end
+
+      context "for an object_double" do
+        let(:dbl) { object_double(ExpiredInstanceInterface.new) }
+        include_examples "expiration"
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/hash_excluding_matcher_spec.rb b/rspec-mocks/spec/rspec/mocks/hash_excluding_matcher_spec.rb
new file mode 100644
index 0000000..c4e52fd
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/hash_excluding_matcher_spec.rb
@@ -0,0 +1,65 @@
+module RSpec
+  module Mocks
+    module ArgumentMatchers
+      RSpec.describe HashExcludingMatcher do
+
+        it "describes itself properly" do
+          expect(HashExcludingMatcher.new(:a => 5).description).to eq "hash_not_including(:a=>5)"
+        end
+
+        describe "passing" do
+          it "matches a hash without the specified key" do
+            expect(hash_not_including(:c)).to be === {:a => 1, :b => 2}
+          end
+
+          it "matches a hash with the specified key, but different value" do
+            expect(hash_not_including(:b => 3)).to be === {:a => 1, :b => 2}
+          end
+
+          it "matches a hash without the specified key, given as anything()" do
+            expect(hash_not_including(:c => anything)).to be === {:a => 1, :b => 2}
+          end
+
+          it "matches an empty hash" do
+            expect(hash_not_including(:a)).to be === {}
+          end
+
+          it "matches a hash without any of the specified keys" do
+            expect(hash_not_including(:a, :b, :c)).to be === { :d => 7 }
+          end
+
+        end
+
+        describe "failing" do
+          it "does not match a non-hash" do
+            expect(hash_not_including(:a => 1)).not_to be === 1
+          end
+
+          it "does not match a hash with a specified key" do
+            expect(hash_not_including(:b)).not_to be === { :b => 2 }
+          end
+
+          it "does not match a hash with the specified key/value pair" do
+            expect(hash_not_including(:b => 2)).not_to be === { :a => 1, :b => 2 }
+          end
+
+          it "does not match a hash with the specified key" do
+            expect(hash_not_including(:a, :b => 3)).not_to be === { :a => 1, :b => 2 }
+          end
+
+          it "does not match a hash with one of the specified keys" do
+            expect(hash_not_including(:a, :b)).not_to be === { :b => 2 }
+          end
+
+          it "does not match a hash with some of the specified keys" do
+            expect(hash_not_including(:a, :b, :c)).not_to be === { :a => 1, :b => 2 }
+          end
+
+          it "does not match a hash with one key/value pair included" do
+            expect(hash_not_including(:a, :b, :c, :d => 7)).not_to be === { :d => 7 }
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/hash_including_matcher_spec.rb b/rspec-mocks/spec/rspec/mocks/hash_including_matcher_spec.rb
new file mode 100644
index 0000000..0874366
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/hash_including_matcher_spec.rb
@@ -0,0 +1,98 @@
+module RSpec
+  module Mocks
+    module ArgumentMatchers
+      RSpec.describe HashIncludingMatcher do
+
+        it "describes itself properly" do
+          expect(HashIncludingMatcher.new(:a => 1).description).to eq "hash_including(:a=>1)"
+        end
+
+        it "describes passed matchers" do
+          description = hash_including(:foo => fake_matcher(Object.new)).description
+
+          expect(description).to include(MatcherHelpers.fake_matcher_description)
+        end
+
+        describe "passing" do
+          it "matches the same hash" do
+            expect(hash_including(:a => 1)).to be === {:a => 1}
+          end
+
+          it "matches a hash with extra stuff" do
+            expect(hash_including(:a => 1)).to be === {:a => 1, :b => 2}
+          end
+
+          describe "when matching against other matchers" do
+            it "matches an int against anything()" do
+              expect(hash_including(:a => anything, :b => 2)).to be === {:a => 1, :b => 2}
+            end
+
+            it "matches a string against anything()" do
+              expect(hash_including(:a => anything, :b => 2)).to be === {:a => "1", :b => 2}
+            end
+
+            it 'can match against arbitrary objects that implement #===' do
+              expect(hash_including(:a => /foo/)).to be === { :a => "foobar" }
+            end
+          end
+
+          describe "when passed only keys or keys mixed with key/value pairs" do
+            it "matches if the key is present" do
+              expect(hash_including(:a)).to be === {:a => 1, :b => 2}
+            end
+
+            it "matches if more keys are present" do
+              expect(hash_including(:a, :b)).to be === {:a => 1, :b => 2, :c => 3}
+            end
+
+            it "matches a string against a given key" do
+              expect(hash_including(:a)).to be === {:a => "1", :b => 2}
+            end
+
+            it "matches if passed one key and one key/value pair" do
+              expect(hash_including(:a, :b => 2)).to be === {:a => 1, :b => 2}
+            end
+
+            it "matches if passed many keys and one key/value pair" do
+              expect(hash_including(:a, :b, :c => 3)).to be === {:a => 1, :b => 2, :c => 3, :d => 4}
+            end
+
+            it "matches if passed many keys and many key/value pairs" do
+              expect(hash_including(:a, :b, :c => 3, :e => 5)).to be === {:a => 1, :b => 2, :c => 3, :d => 4, :e => 5}
+            end
+          end
+        end
+
+        describe "failing" do
+          it "does not match a non-hash" do
+            expect(hash_including(:a => 1)).not_to be === 1
+          end
+
+          it "does not match a hash with a missing key" do
+            expect(hash_including(:a => 1)).not_to be === { :b => 2 }
+          end
+
+          it "does not match a hash with a missing key" do
+            expect(hash_including(:a)).not_to be === { :b => 2 }
+          end
+
+          it "does not match an empty hash with a given key" do
+            expect(hash_including(:a)).not_to be === {}
+          end
+
+          it "does not match a hash with a missing key when one pair is matching" do
+            expect(hash_including(:a, :b => 2)).not_to be === { :b => 2 }
+          end
+
+          it "does not match a hash with an incorrect value" do
+            expect(hash_including(:a => 1, :b => 2)).not_to be === { :a => 1, :b => 3 }
+          end
+
+          it "does not match when values are nil but keys are different" do
+            expect(hash_including(:a => nil)).not_to be === { :b => nil }
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/instance_method_stasher_spec.rb b/rspec-mocks/spec/rspec/mocks/instance_method_stasher_spec.rb
new file mode 100644
index 0000000..ac2eadb
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/instance_method_stasher_spec.rb
@@ -0,0 +1,72 @@
+module RSpec
+  module Mocks
+    RSpec.describe InstanceMethodStasher do
+      class ExampleClass
+        def hello
+          :hello_defined_on_class
+        end
+      end
+
+      def singleton_class_for(obj)
+        class << obj; self; end
+      end
+
+      def stasher_for(obj, method_name)
+        InstanceMethodStasher.new(obj, method_name)
+      end
+
+      it "stashes the current implementation of an instance method so it can be temporarily replaced" do
+        obj = Object.new
+        def obj.hello; :hello_defined_on_singleton_class; end;
+
+        stashed_method = stasher_for(obj, :hello)
+        stashed_method.stash
+
+        with_isolated_stderr { def obj.hello; :overridden_hello; end }
+        expect(obj.hello).to eql :overridden_hello
+
+        stashed_method.restore
+        expect(obj.hello).to eql :hello_defined_on_singleton_class
+      end
+
+      it "stashes private instance methods" do
+        obj = Object.new
+        def obj.hello; :hello_defined_on_singleton_class; end;
+        singleton_class_for(obj).__send__(:private, :hello)
+
+        stashed_method = stasher_for(obj, :hello)
+        stashed_method.stash
+
+        with_isolated_stderr { def obj.hello; :overridden_hello; end }
+        stashed_method.restore
+        expect(obj.send(:hello)).to eql :hello_defined_on_singleton_class
+      end
+
+      it "only stashes methods directly defined on the given class, not its ancestors" do
+        obj = ExampleClass.new
+
+        stashed_method = stasher_for(obj, :hello)
+        stashed_method.stash
+
+        def obj.hello; :overridden_hello; end;
+        expect(obj.hello).to eql :overridden_hello
+
+        stashed_method.restore
+        expect(obj.hello).to eql :overridden_hello
+      end
+
+      it "does not unnecessarily create obfuscated aliased methods", :if => (RUBY_VERSION.to_f > 1.8) do
+        obj = Object.new
+        def obj.hello; :hello_defined_on_singleton_class; end;
+
+        stashed_method = stasher_for(obj, :hello)
+
+        expect {
+          stashed_method.stash
+        }.not_to change { obj.methods.count }
+
+        expect(obj.methods.grep(/rspec/)).to eq([])
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/marshal_extension_spec.rb b/rspec-mocks/spec/rspec/mocks/marshal_extension_spec.rb
new file mode 100644
index 0000000..a44f636
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/marshal_extension_spec.rb
@@ -0,0 +1,67 @@
+RSpec.describe Marshal, 'extensions' do
+  # An object that raises when code attempts to dup it.
+  #
+  # Because we manipulate the internals of RSpec::Mocks.space below, we need
+  # an object that simply blows up when #dup is called without using any
+  # partial mocking or stubbing from rspec-mocks itself.
+  class UndupableObject
+    def dup
+      raise NotImplementedError
+    end
+  end
+
+  describe '#dump' do
+    context 'when rspec-mocks has been fully initialized' do
+      include_context "with monkey-patched marshal"
+
+      it 'duplicates objects with stubbed or mocked implementations before serialization' do
+        obj = double(:foo => "bar")
+
+        serialized = Marshal.dump(obj)
+        expect(Marshal.load(serialized)).to be_an(obj.class)
+      end
+
+      it 'does not duplicate other objects before serialization' do
+        obj = UndupableObject.new
+
+        serialized = Marshal.dump(obj)
+        expect(Marshal.load(serialized)).to be_an(UndupableObject)
+      end
+
+      it 'does not duplicate nil before serialization' do
+        serialized = Marshal.dump(nil)
+        expect(Marshal.load(serialized)).to be_nil
+      end
+
+      specify 'applying and unapplying patch is idempotent' do
+        obj = double(:foo => "bar")
+        config = RSpec::Mocks.configuration
+
+        config.patch_marshal_to_support_partial_doubles = true
+        config.patch_marshal_to_support_partial_doubles = true
+        serialized = Marshal.dump(obj)
+        expect(Marshal.load(serialized)).to be_an(obj.class)
+        config.patch_marshal_to_support_partial_doubles = false
+        config.patch_marshal_to_support_partial_doubles = false
+        expect { Marshal.dump(obj) }.to raise_error(TypeError)
+      end
+    end
+
+    context 'outside the per-test lifecycle' do
+      def outside_per_test_lifecycle
+        RSpec::Mocks.teardown
+        yield
+      ensure
+        RSpec::Mocks.setup
+      end
+
+      it 'does not duplicate the object before serialization' do
+        obj = UndupableObject.new
+        outside_per_test_lifecycle do
+          serialized = Marshal.dump(obj)
+          expect(Marshal.load(serialized)).to be_an(UndupableObject)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/matchers/have_received_spec.rb b/rspec-mocks/spec/rspec/mocks/matchers/have_received_spec.rb
new file mode 100644
index 0000000..7bda18a
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/matchers/have_received_spec.rb
@@ -0,0 +1,513 @@
+module RSpec
+  module Mocks
+    RSpec.describe Matchers::HaveReceived do
+      describe "expect(...).to have_received" do
+        it 'passes when the double has received the given message' do
+          dbl = double_with_met_expectation(:expected_method)
+          expect(dbl).to have_received(:expected_method)
+        end
+
+        it 'passes when a null object has received the given message' do
+          dbl = null_object_with_met_expectation(:expected_method)
+          expect(dbl).to have_received(:expected_method)
+        end
+
+        it 'fails when the double has not received the given message' do
+          dbl = double_with_unmet_expectation(:expected_method)
+
+          expect {
+            expect(dbl).to have_received(:expected_method)
+          }.to raise_error(/expected: 1 time/)
+        end
+
+        it 'fails when a null object has not received the given message' do
+          dbl = double.as_null_object
+
+          expect {
+            expect(dbl).to have_received(:expected_method)
+          }.to raise_error(/expected: 1 time/)
+        end
+
+        it 'fails when the method has not been previously stubbed' do
+          dbl = double
+
+          expect {
+            expect(dbl).to have_received(:expected_method)
+          }.to raise_error(/method has not been stubbed/)
+        end
+
+        it 'fails when the method has been mocked' do
+          dbl = double
+          expect(dbl).to receive(:expected_method)
+          dbl.expected_method
+
+          expect {
+            expect(dbl).to have_received(:expected_method)
+          }.to raise_error(/method has been mocked instead of stubbed/)
+        end
+
+        it "takes a curly-bracket block and yields the arguments given to the stubbed method call" do
+          dbl = double(:foo => nil)
+          yielded = []
+          dbl.foo(:a, :b, :c)
+          expect(dbl).to have_received(:foo) { |*args|
+            yielded << args
+          }
+          expect(yielded).to include([:a,:b,:c])
+        end
+
+        it "takes a do-end block and yields the arguments given to the stubbed method call" do
+          dbl = double(:foo => nil)
+          yielded = []
+          dbl.foo(:a, :b, :c)
+          expect(dbl).to have_received(:foo) do |*args|
+            yielded << args
+          end
+          expect(yielded).to include([:a,:b,:c])
+        end
+
+        it "passes if expectations against the yielded arguments pass" do
+          dbl = double(:foo => nil)
+          dbl.foo(42)
+          expect {
+            expect(dbl).to have_received(:foo) { |arg|
+              expect(arg).to eq(42)
+            }
+          }.to_not raise_error
+        end
+
+        it "fails if expectations against the yielded arguments fail" do
+          dbl = double(:foo => nil)
+          dbl.foo(43)
+          expect {
+            expect(dbl).to have_received(:foo) { |arg|
+              expect(arg).to eq(42)
+            }
+          }.to raise_error(RSpec::Expectations::ExpectationNotMetError)
+        end
+
+        it 'gives precedence to a `{ ... }` block when both forms are provided ' +
+           'since that form actually binds to `receive`' do
+          dbl = double(:foo => nil)
+          called = []
+          dbl.foo
+          expect(dbl).to have_received(:foo) { called << :curly } do
+            called << :do_end
+          end
+          expect(called).to include(:curly)
+          expect(called).not_to include(:do_end)
+        end
+
+        it 'resets expectations on class methods when mocks are reset' do
+          dbl = Object
+          allow(dbl).to receive(:expected_method)
+          dbl.expected_method
+          reset dbl
+          allow(dbl).to receive(:expected_method)
+
+          expect {
+            expect(dbl).to have_received(:expected_method)
+          }.to raise_error(/0 times/)
+        end
+
+        context "with" do
+          it 'passes when the given args match the args used with the message' do
+            dbl = double_with_met_expectation(:expected_method, :expected, :args)
+            expect(dbl).to have_received(:expected_method).with(:expected, :args)
+          end
+
+          it 'fails when the given args do not match the args used with the message' do
+            dbl = double_with_met_expectation(:expected_method, :expected, :args)
+
+            expect {
+              expect(dbl).to have_received(:expected_method).with(:unexpected, :args)
+            }.to raise_error(/with unexpected arguments/)
+          end
+        end
+
+        it 'generates a useful description' do
+          matcher = have_received(:expected_method).with(:expected_args).once
+          expect(matcher.description).to eq 'have received expected_method(:expected_args) 1 time'
+        end
+
+        it 'can generate a description after mocks have been torn down (e.g. when rspec-core requests it)' do
+          matcher = have_received(:expected_method).with(:expected_args).once
+          matcher.matches?(double(:expected_method => 1))
+          RSpec::Mocks.teardown
+          expect(matcher.description).to eq 'have received expected_method(:expected_args) 1 time'
+        end
+
+        context "counts" do
+          let(:the_dbl) { double(:expected_method => nil) }
+
+          before do
+            the_dbl.expected_method
+            the_dbl.expected_method
+            the_dbl.expected_method
+          end
+
+          context "exactly" do
+            it 'passes when the message was received the given number of times' do
+              expect(the_dbl).to have_received(:expected_method).exactly(3).times
+            end
+
+            it 'fails when the message was received more times than expected' do
+              expect {
+                expect(the_dbl).to have_received(:expected_method).exactly(1).times
+              }.to raise_error(/expected: 1 time.*received: 3 times/m)
+              expect {
+                expect(the_dbl).to have_received(:expected_method).exactly(2).times
+              }.to raise_error(/expected: 2 times.*received: 3 times/m)
+              expect {
+                the_dbl.expected_method
+                the_dbl.expected_method
+                expect(the_dbl).to have_received(:expected_method).exactly(2).times
+              }.to raise_error(/expected: 2 times.*received: 5 times/m)
+            end
+
+            it 'fails when the message was received fewer times' do
+              expect {
+                expect(the_dbl).to have_received(:expected_method).exactly(4).times
+              }.to raise_error(/expected: 4 times.*received: 3 times/m)
+            end
+          end
+
+          context 'at_least' do
+            it 'passes when the message was received the given number of times' do
+              expect(the_dbl).to have_received(:expected_method).at_least(3).times
+            end
+
+            it 'passes when the message was received more times' do
+              expect(the_dbl).to have_received(:expected_method).at_least(2).times
+            end
+
+            it 'fails when the message was received fewer times' do
+              expect {
+                expect(the_dbl).to have_received(:expected_method).at_least(4).times
+              }.to raise_error(/expected: at least 4 times.*received: 3 times/m)
+            end
+          end
+
+          context 'at_most' do
+            it 'passes when the message was received the given number of times' do
+              expect(the_dbl).to have_received(:expected_method).at_most(3).times
+            end
+
+            it 'passes when the message was received fewer times' do
+              expect(the_dbl).to have_received(:expected_method).at_most(4).times
+            end
+
+            it 'fails when the message was received more times' do
+              expect {
+                expect(the_dbl).to have_received(:expected_method).at_most(2).times
+              }.to raise_error(/expected: at most 2 times.*received: 3 times/m)
+            end
+          end
+
+          context 'once' do
+            it 'passes when the message was received once' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              expect(dbl).to have_received(:expected_method).once
+            end
+
+            it 'fails when the message was never received' do
+              dbl = double(:expected_method => nil)
+
+              expect {
+                expect(dbl).to have_received(:expected_method).once
+              }.to raise_error(/expected: 1 time.*received: 0 times/m)
+            end
+
+            it 'fails when the message was received twice' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              dbl.expected_method
+
+              expect {
+                expect(dbl).to have_received(:expected_method).once
+              }.to raise_error(/expected: 1 time.*received: 2 times/m)
+            end
+          end
+
+          context 'twice' do
+            it 'passes when the message was received twice' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              dbl.expected_method
+
+              expect(dbl).to have_received(:expected_method).twice
+            end
+
+            it 'fails when the message was received once' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+
+              expect {
+                expect(dbl).to have_received(:expected_method).twice
+              }.to raise_error(/expected: 2 times.*received: 1 time/m)
+            end
+
+            it 'fails when the message was received thrice' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              dbl.expected_method
+              dbl.expected_method
+
+              expect {
+                expect(dbl).to have_received(:expected_method).twice
+              }.to raise_error(/expected: 2 times.*received: 3 times/m)
+            end
+          end
+
+          context 'thrice' do
+            it 'passes when the message was received thrice' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              dbl.expected_method
+              dbl.expected_method
+
+              expect(dbl).to have_received(:expected_method).thrice
+            end
+
+            it 'fails when the message was received less than three times' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              dbl.expected_method
+
+              expect {
+                expect(dbl).to have_received(:expected_method).thrice
+              }.to raise_error(/expected: 3 times.*received: 2 times/m)
+            end
+
+            it 'fails when the message was received more than three times' do
+              dbl = double(:expected_method => nil)
+              dbl.expected_method
+              dbl.expected_method
+              dbl.expected_method
+              dbl.expected_method
+
+              expect {
+                expect(dbl).to have_received(:expected_method).thrice
+              }.to raise_error(/expected: 3 times.*received: 4 times/m)
+            end
+          end
+        end
+
+        context 'ordered' do
+          let(:the_dbl) { double :one => 1, :two => 2, :three => 3 }
+
+          it 'passes when the messages were received in order' do
+            the_dbl.one
+            the_dbl.two
+
+            expect(the_dbl).to have_received(:one).ordered
+            expect(the_dbl).to have_received(:two).ordered
+          end
+
+          it 'passes with exact receive counts when received in order' do
+            3.times { the_dbl.one }
+            2.times { the_dbl.two }
+            the_dbl.three
+
+            expect(the_dbl).to have_received(:one).thrice.ordered
+            expect(the_dbl).to have_received(:two).twice.ordered
+            expect(the_dbl).to have_received(:three).once.ordered
+          end
+
+          it 'passes with at most receive counts when received in order', :ordered_and_vauge_counts_unsupported do
+            the_dbl.one
+            the_dbl.one
+            the_dbl.two
+
+            expect(the_dbl).to have_received(:one).at_most(3).times.ordered
+            expect(the_dbl).to have_received(:one).at_most(:thrice).times.ordered
+            expect(the_dbl).to have_received(:two).once.ordered
+          end
+
+          it 'passes with at least receive counts when received in order', :ordered_and_vauge_counts_unsupported do
+            the_dbl.one
+            the_dbl.one
+            the_dbl.two
+
+            expect(the_dbl).to have_received(:one).at_least(1).times.ordered
+            expect(the_dbl).to have_received(:two).once.ordered
+          end
+
+          it 'fails with exact receive counts when received out of order' do
+            the_dbl.one
+            the_dbl.two
+            the_dbl.one
+
+            expect {
+              expect(the_dbl).to have_received(:one).twice.ordered
+              expect(the_dbl).to have_received(:two).once.ordered
+            }.to raise_error(/received :two out of order/m)
+          end
+
+          it "fails with at most receive counts when recieved out of order", :ordered_and_vauge_counts_unsupported do
+            the_dbl.one
+            the_dbl.two
+            the_dbl.one
+
+            expect {
+              expect(the_dbl).to have_received(:one).at_most(2).times.ordered
+              expect(the_dbl).to have_received(:two).once.ordered
+            }.to raise_error(/received :two out of order/m)
+          end
+
+          it "fails with at least receive counts when recieved out of order", :ordered_and_vauge_counts_unsupported do
+            the_dbl.one
+            the_dbl.two
+            the_dbl.one
+
+            expect {
+              expect(the_dbl).to have_received(:one).at_least(1).times.ordered
+              expect(the_dbl).to have_received(:two).once.ordered
+            }.to raise_error(/received :two out of order/m)
+          end
+
+          it 'fails when the messages are received out of order' do
+            the_dbl.two
+            the_dbl.one
+
+            expect {
+              expect(the_dbl).to have_received(:one).ordered
+              expect(the_dbl).to have_received(:two).ordered
+            }.to raise_error(/received :two out of order/m)
+          end
+
+          context "when used with `with`" do
+            before do
+              the_dbl.one(1)
+              the_dbl.one(2)
+            end
+
+            it "passes when the order lines up" do
+              expect(the_dbl).to have_received(:one).with(1).ordered
+              expect(the_dbl).to have_received(:one).with(2).ordered
+            end
+
+            it "fails when the order is not matched" do
+              expect {
+                expect(the_dbl).to have_received(:one).with(2).ordered
+                expect(the_dbl).to have_received(:one).with(1).ordered
+              }.to fail_with(/received :one out of order/m)
+            end
+          end
+
+          context "when used on individually allowed messages" do
+            before do
+              allow(the_dbl).to receive(:foo)
+              allow(the_dbl).to receive(:bar)
+
+              the_dbl.foo
+              the_dbl.bar
+            end
+
+            it 'passes when the messages were received in order' do
+              expect(the_dbl).to have_received(:foo).ordered
+              expect(the_dbl).to have_received(:bar).ordered
+            end
+
+            it 'fails when the messages are received out of order' do
+              expect {
+                expect(the_dbl).to have_received(:bar).ordered
+                expect(the_dbl).to have_received(:foo).ordered
+              }.to raise_error(/received :foo out of order/m)
+            end
+          end
+        end
+      end
+
+      describe "expect(...).not_to have_received" do
+        it 'passes when the double has not received the given message' do
+          dbl = double_with_unmet_expectation(:expected_method)
+          expect(dbl).not_to have_received(:expected_method)
+        end
+
+        it 'fails when the double has received the given message' do
+          dbl = double_with_met_expectation(:expected_method)
+
+          expect {
+            expect(dbl).not_to have_received(:expected_method)
+          }.to raise_error(/expected: 0 times.*received: 1 time/m)
+        end
+
+        it 'fails when the method has not been previously stubbed' do
+          dbl = double
+
+          expect {
+            expect(dbl).not_to have_received(:expected_method)
+          }.to raise_error(/method has not been stubbed/)
+        end
+
+        context "with" do
+          it 'passes when the given args do not match the args used with the message' do
+            dbl = double_with_met_expectation(:expected_method, :expected, :args)
+            expect(dbl).not_to have_received(:expected_method).with(:unexpected, :args)
+          end
+
+          it 'fails when the given args match the args used with the message' do
+            dbl = double_with_met_expectation(:expected_method, :expected, :args)
+
+            expect {
+              expect(dbl).not_to have_received(:expected_method).with(:expected, :args)
+            }.to raise_error(/expected: 0 times.*received: 1 time/m) # TODO: better message
+          end
+        end
+
+        %w(exactly at_least at_most times once twice).each do |constraint|
+          it "does not allow #{constraint} to be used because it creates confusion" do
+            dbl = double_with_unmet_expectation(:expected_method)
+            expect {
+              expect(dbl).not_to have_received(:expected_method).send(constraint)
+            }.to raise_error(/can't use #{constraint} when negative/)
+          end
+        end
+      end
+
+      describe "allow(...).to have_received" do
+        it "fails because its nonsensical" do
+          expect {
+            allow(double).to have_received(:some_method)
+          }.to fail_with("Using allow(...) with the `have_received` matcher is not supported as it would have no effect.")
+        end
+      end
+
+      describe "allow_any_instance_of(...).to have_received" do
+        it "fails because its nonsensical" do
+          expect {
+            allow_any_instance_of(double).to have_received(:some_method)
+          }.to fail_with("Using allow_any_instance_of(...) with the `have_received` matcher is not supported.")
+        end
+      end
+
+      describe "expect_any_instance_of(...).to have_received" do
+        it "fails because we dont want to support it" do
+          expect {
+            expect_any_instance_of(double).to have_received(:some_method)
+          }.to fail_with("Using expect_any_instance_of(...) with the `have_received` matcher is not supported.")
+        end
+      end
+
+      def double_with_met_expectation(method_name, *args)
+        double = double_with_unmet_expectation(method_name)
+        meet_expectation(double, method_name, *args)
+      end
+
+      def null_object_with_met_expectation(method_name, *args)
+        meet_expectation(double.as_null_object, method_name, *args)
+      end
+
+      def meet_expectation(double, method_name, *args)
+        double.send(method_name, *args)
+        double
+      end
+
+      def double_with_unmet_expectation(method_name)
+        double('double', method_name => true)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/matchers/receive_message_chain_spec.rb b/rspec-mocks/spec/rspec/mocks/matchers/receive_message_chain_spec.rb
new file mode 100644
index 0000000..ea22818
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/matchers/receive_message_chain_spec.rb
@@ -0,0 +1,242 @@
+module RSpec::Mocks::Matchers
+  RSpec.describe "receive_message_chain" do
+    let(:object) { double(:object) }
+
+    context "with only the expect syntax enabled" do
+      include_context "with syntax", :expect
+
+      it "errors with a negative allowance" do
+        expect {
+          allow(object).not_to receive_message_chain(:to_a)
+        }.to raise_error(RSpec::Mocks::NegationUnsupportedError)
+      end
+
+      it "errors with a negative expectation" do
+        expect {
+          expect(object).not_to receive_message_chain(:to_a)
+        }.to raise_error(RSpec::Mocks::NegationUnsupportedError)
+      end
+
+      it "errors with a negative any_instance expectation" do
+        expect {
+          expect_any_instance_of(Object).not_to receive_message_chain(:to_a)
+        }.to raise_error(RSpec::Mocks::NegationUnsupportedError)
+      end
+
+      it "errors with a negative any_instance allowance" do
+        expect {
+          allow_any_instance_of(Object).not_to receive_message_chain(:to_a)
+        }.to raise_error(RSpec::Mocks::NegationUnsupportedError)
+      end
+
+      it "works with a do block" do
+        allow(object).to receive_message_chain(:to_a, :length) do
+          3
+        end
+
+        expect(object.to_a.length).to eq(3)
+      end
+
+      it "works with a {} block" do
+        allow(object).to receive_message_chain(:to_a, :length) { 3 }
+
+        expect(object.to_a.length).to eq(3)
+      end
+
+      it "gives the { } block prescedence over the do block" do
+        allow(object).to receive_message_chain(:to_a, :length) { 3 } do
+          4
+        end
+
+        expect(object.to_a.length).to eq(3)
+      end
+
+      it "works with and_return" do
+        allow(object).to receive_message_chain(:to_a, :length).and_return(3)
+
+        expect(object.to_a.length).to eq(3)
+      end
+
+      it "can constrain the return value by the argument to the last call" do
+        allow(object).to receive_message_chain(:one, :plus).with(1) { 2 }
+        allow(object).to receive_message_chain(:one, :plus).with(2) { 3 }
+        expect(object.one.plus(1)).to eq(2)
+        expect(object.one.plus(2)).to eq(3)
+      end
+
+      it "works with and_call_original", :pending => "See https://github.com/rspec/rspec-mocks/pull/467#issuecomment-28631621" do
+        list = [1, 2, 3]
+        expect(list).to receive_message_chain(:to_a, :length).and_call_original
+        expect(list.to_a.length).to eq(3)
+      end
+
+      it "fails with and_call_original when the entire chain is not called", :pending => "See https://github.com/rspec/rspec-mocks/pull/467#issuecomment-28631621" do
+        list = [1, 2, 3]
+        expect(list).to receive_message_chain(:to_a, :length).and_call_original
+        expect(list.to_a).to eq([1, 2, 3])
+      end
+
+      it "works with and_raise" do
+        allow(object).to receive_message_chain(:to_a, :length).and_raise(StandardError.new("hi"))
+
+        expect { object.to_a.length }.to raise_error(StandardError, "hi")
+      end
+
+      it "works with and_throw" do
+        allow(object).to receive_message_chain(:to_a, :length).and_throw(:nope)
+
+        expect { object.to_a.length }.to throw_symbol(:nope)
+      end
+
+      it "works with and_yield" do
+        allow(object).to receive_message_chain(:to_a, :length).and_yield(3)
+
+        expect { |blk| object.to_a.length(&blk) }.to yield_with_args(3)
+      end
+
+      it "works with a string of messages to chain" do
+        allow(object).to receive_message_chain("to_a.length").and_yield(3)
+
+        expect { |blk| object.to_a.length(&blk) }.to yield_with_args(3)
+      end
+
+      it "works with a hash return as the last argument in the chain" do
+        allow(object).to receive_message_chain(:to_a, :length => 3)
+
+        expect(object.to_a.length).to eq(3)
+      end
+
+      it "accepts any number of arguments to the stubbed messages" do
+        allow(object).to receive_message_chain(:msg1, :msg2).and_return(:return_value)
+
+        expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
+      end
+
+      it "accepts any number of arguments to the stubbed messages with an inline hash return value" do
+        allow(object).to receive_message_chain(:msg1, :msg2 => :return_value)
+
+        expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
+      end
+
+      it "raises when expect is used and some of the messages in the chain aren't called" do
+        expect {
+          expect(object).to receive_message_chain(:to_a, :farce, :length => 3)
+          object.to_a
+          verify_all
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "raises when expect is used and all but the last message in the chain are called" do
+        expect {
+          expect(object).to receive_message_chain(:foo, :bar, :baz)
+          object.foo.bar
+          verify_all
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "does not raise when expect is used and the entire chain is called" do
+        expect {
+          expect(object).to receive_message_chain(:to_a, :length => 3)
+          object.to_a.length
+          verify_all
+        }.not_to raise_error
+      end
+
+      it "works with allow_any_instance" do
+        o = Object.new
+
+        allow_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3)
+
+        expect(o.to_a.length).to eq(3)
+      end
+
+      it "stubs already stubbed instances when using `allow_any_instance_of`" do
+        o = Object.new
+        allow(o).to receive(:foo).and_return(dbl = double)
+        expect(o.foo).to be(dbl)
+
+        allow_any_instance_of(Object).to receive_message_chain(:foo, :bar).and_return("bazz")
+        expect(o.foo.bar).to eq("bazz")
+      end
+
+      it "fails when with expect_any_instance_of is used and the entire chain is not called" do
+        expect {
+          expect_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3)
+          verify_all
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "affects previously stubbed instances when `expect_any_instance_of` is called" do
+        o = Object.new
+        allow(o).to receive(:foo).and_return(double)
+
+        expect_any_instance_of(Object).to receive_message_chain(:foo, :bar => 3)
+        expect(o.foo.bar).to eq(3)
+      end
+
+      it "passes when with expect_any_instance_of is used and the entire chain is called" do
+        o = Object.new
+
+        expect_any_instance_of(Object).to receive_message_chain(:to_a, :length => 3)
+        o.to_a.length
+      end
+
+      it "works with expect where the first level of the chain is already expected" do
+        o = Object.new
+        expect(o).to receive(:foo).and_return(double)
+        expect(o).to receive_message_chain(:foo, :bar, :baz)
+
+        o.foo.bar.baz
+      end
+
+      it "works with allow where the first level of the chain is already expected" do
+        o = Object.new
+        expect(o).to receive(:foo).and_return(double)
+        allow(o).to receive_message_chain(:foo, :bar, :baz).and_return(3)
+
+        expect(o.foo.bar.baz).to eq(3)
+      end
+
+      it "works with expect where the first level of the chain is already stubbed" do
+        o = Object.new
+        allow(o).to receive(:foo).and_return(double)
+        expect(o).to receive_message_chain(:foo, :bar, :baz)
+
+        o.foo.bar.baz
+      end
+
+      it "works with allow where the first level of the chain is already stubbed" do
+        o = Object.new
+        allow(o).to receive(:foo).and_return(double)
+        allow(o).to receive_message_chain(:foo, :bar, :baz).and_return(3)
+
+        expect(o.foo.bar.baz).to eq(3)
+      end
+
+      it "provides a matcher description (when passing a string)" do
+        matcher = receive_message_chain("foo.bar.bazz")
+        expect(matcher.description).to eq("receive message chain foo.bar.bazz")
+      end
+
+      it "provides a matcher description (when passing symbols)" do
+        matcher = receive_message_chain(:foo, :bar, :bazz)
+        expect(matcher.description).to eq("receive message chain foo.bar.bazz")
+      end
+
+      it "provides a matcher description (when passing symbols and a hash)" do
+        matcher = receive_message_chain(:foo, :bar, :bazz => 3)
+        expect(matcher.description).to eq("receive message chain foo.bar.bazz")
+      end
+    end
+
+    context "when the expect and should syntaxes are enabled" do
+      include_context "with syntax", [:expect, :should]
+
+      it "stubs the message correctly" do
+        allow(object).to receive_message_chain(:to_a, :length)
+
+        expect { object.to_a.length }.not_to raise_error
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/matchers/receive_messages_spec.rb b/rspec-mocks/spec/rspec/mocks/matchers/receive_messages_spec.rb
new file mode 100644
index 0000000..22d0880
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/matchers/receive_messages_spec.rb
@@ -0,0 +1,154 @@
+module RSpec
+  module Mocks
+    RSpec.shared_examples "complains when given blocks" do
+      it "complains if a { } block is given" do
+        expect {
+          target.to receive_messages(:a => 1) { "implementation" }
+        }.to raise_error "Implementation blocks aren't supported with `receive_messages`"
+      end
+
+      it "complains if a do; end; block is given" do
+        expect {
+          target.to receive_messages(:a => 1) do
+            "implementation"
+          end
+        }.to raise_error "Implementation blocks aren't supported with `receive_messages`"
+      end
+    end
+
+    RSpec.shared_examples "handles partially mocked objects correctly" do
+      let(:obj) { Struct.new(:a).new('original') }
+
+      it "resets partially mocked objects correctly" do
+        target.to receive_messages(:a => 1, :b => 2)
+
+        expect {
+          reset obj
+        }.to change { obj.a }.from(1).to("original")
+      end
+    end
+
+    RSpec.describe "allow(...).to receive_messages(:a => 1, :b => 2)" do
+      let(:obj) { double "Object" }
+      let(:target) { allow(obj) }
+
+      it "allows the object to respond to multiple messages" do
+        allow(obj).to receive_messages(:a => 1, :b => 2)
+        expect(obj.a).to eq 1
+        expect(obj.b).to eq 2
+      end
+
+      it_behaves_like "complains when given blocks"
+      it_behaves_like "handles partially mocked objects correctly"
+    end
+
+    RSpec.describe "allow_any_instance_of(...).to receive_messages(:a => 1, :b => 2)" do
+      let(:obj) { Object.new }
+      let(:target) { allow_any_instance_of(Object) }
+
+      it "allows the object to respond to multiple messages" do
+        allow_any_instance_of(Object).to receive_messages(:a => 1, :b => 2)
+        expect(obj.a).to eq 1
+        expect(obj.b).to eq 2
+      end
+
+      it "updates stubs on instances with existing stubs" do
+        allow(obj).to receive(:a).and_return(3)
+        expect(obj.a).to eq(3)
+
+        allow_any_instance_of(Object).to receive_messages(:a => 1, :b => 2)
+        expect(obj.a).to eq 1
+        expect(obj.b).to eq 2
+      end
+
+      it_behaves_like "complains when given blocks"
+    end
+
+    RSpec.describe "expect(...).to receive_messages(:a => 1, :b => 2)" do
+      let(:obj) { double "Object" }
+      let(:target) { expect(obj) }
+
+      let(:expectation_error) do
+        failure = nil
+        begin
+          verify_all
+        rescue RSpec::Mocks::MockExpectationError => error
+          failure = error
+        end
+        failure
+      end
+
+      it "sets up multiple expectations" do
+        expect(obj).to receive_messages(:a => 1, :b => 2)
+        obj.a
+        expect { verify_all }.to raise_error RSpec::Mocks::MockExpectationError
+      end
+
+      it 'fails with a sensible message' do
+        expect(obj).to receive_messages(:a => 1, :b => 2)
+        obj.b
+        expect(expectation_error.to_s).to eq %Q{(Double "Object").a(no args)\n    expected: 1 time with any arguments\n    received: 0 times}
+      end
+
+      it 'fails with the correct location' do
+        expect(obj).to receive_messages(:a => 1, :b => 2); line = __LINE__
+        expect(expectation_error.backtrace[0]).to match(/#{__FILE__}:#{line}/)
+      end
+
+      it_behaves_like "complains when given blocks"
+      it_behaves_like "handles partially mocked objects correctly"
+
+      it "provides a matcher description" do
+        messages = { :a => 1, :b => 2 }
+        matcher = receive_messages(messages)
+        expect(matcher.description).to eq("receive messages: #{messages.inspect}")
+      end
+    end
+
+    RSpec.describe "expect_any_instance_of(...).to receive_messages(:a => 1, :b => 2)" do
+      let(:obj) { Object.new }
+      let(:target) { expect_any_instance_of(Object) }
+
+      it "sets up multiple expectations" do
+        expect_any_instance_of(Object).to receive_messages(:a => 1, :b => 2)
+        obj.a
+        expect { RSpec::Mocks.space.verify_all }.to raise_error RSpec::Mocks::MockExpectationError
+        RSpec::Mocks.space.reset_all
+      end
+
+      it_behaves_like "complains when given blocks"
+    end
+
+    RSpec.describe "negative expectation failure" do
+      let(:obj) { Object.new }
+
+      example "allow(...).to_not receive_messages(:a => 1, :b => 2)" do
+        expect { allow(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+          raise_error "`allow(...).to_not receive_messages` is not supported "+
+                      "since it doesn't really make sense. What would it even mean?"
+        )
+      end
+
+      example "allow_any_instance_of(...).to_not receive_messages(:a => 1, :b => 2)" do
+        expect { allow_any_instance_of(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+          raise_error "`allow_any_instance_of(...).to_not receive_messages` is not supported "+
+                      "since it doesn't really make sense. What would it even mean?"
+        )
+      end
+
+      example "expect(...).to_not receive_messages(:a => 1, :b => 2)" do
+        expect { expect(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+          raise_error "`expect(...).to_not receive_messages` is not supported "+
+                      "since it doesn't really make sense. What would it even mean?"
+        )
+      end
+
+      example "expect_any_instance_of(...).to_not receive_messages(:a => 1, :b => 2)" do
+        expect { expect_any_instance_of(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+          raise_error "`expect_any_instance_of(...).to_not receive_messages` is not supported "+
+                      "since it doesn't really make sense. What would it even mean?"
+        )
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/matchers/receive_spec.rb b/rspec-mocks/spec/rspec/mocks/matchers/receive_spec.rb
new file mode 100644
index 0000000..a6c2058
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/matchers/receive_spec.rb
@@ -0,0 +1,538 @@
+module RSpec
+  module Mocks
+    RSpec.describe Matchers::Receive do
+      include_context "with syntax", :expect
+
+      describe "expectations/allowances on any instance recorders" do
+        include_context "with syntax", [:expect, :should]
+
+        it "warns about allow(Klass.any_instance).to receive..." do
+          expect(RSpec).to receive(:warning).with(/allow.*any_instance.*is probably not what you meant.*allow_any_instance_of.*instead/)
+          allow(Object.any_instance).to receive(:foo)
+        end
+
+        it "includes the correct call site in the allow warning" do
+          expect_warning_with_call_site(__FILE__, __LINE__ + 1)
+          allow(Object.any_instance).to receive(:foo)
+        end
+
+        it "warns about expect(Klass.any_instance).to receive..." do
+          expect(RSpec).to receive(:warning).with(/expect.*any_instance.*is probably not what you meant.*expect_any_instance_of.*instead/)
+          any_instance_proxy = Object.any_instance
+          expect(any_instance_proxy).to receive(:foo)
+          any_instance_proxy.foo
+        end
+
+        it "includes the correct call site in the expect warning" do
+          any_instance_proxy = Object.any_instance
+          expect_warning_with_call_site(__FILE__, __LINE__ + 1)
+          expect(any_instance_proxy).to receive(:foo)
+          any_instance_proxy.foo
+        end
+      end
+
+      shared_examples "a receive matcher" do |*options|
+        it 'allows the caller to configure how the subject responds' do
+          wrapped.to receive(:foo).and_return(5)
+          expect(receiver.foo).to eq(5)
+        end
+
+        it 'allows the caller to constrain the received arguments' do
+          wrapped.to receive(:foo).with(:a)
+          receiver.foo(:a)
+
+          expect {
+            receiver.foo(:b)
+          }.to raise_error(/received :foo with unexpected arguments/)
+        end
+
+        it 'allows the caller to constrain the received arguments by matcher' do
+          wrapped.to receive(:foo).with an_instance_of Fixnum
+          expect {
+            receiver.foo(1.1)
+          }.to raise_error(/expected.*\(an instance of Fixnum\)/)
+          receiver.foo(1)
+        end
+
+        it 'allows a `do...end` block implementation to be provided' do
+          wrapped.to receive(:foo) do
+            4
+          end
+
+          expect(receiver.foo).to eq(4)
+        end
+
+        it 'allows chaining off a `do...end` block implementation to be provided' do
+          wrapped.to receive(:foo) do
+            4
+          end.and_return(6)
+
+          expect(receiver.foo).to eq(6)
+        end
+
+        it 'allows a `{ ... }` block implementation to be provided' do
+          wrapped.to receive(:foo) { 5 }
+          expect(receiver.foo).to eq(5)
+        end
+
+        it 'gives precedence to a `{ ... }` block when both forms are provided ' +
+           'since that form actually binds to `receive`' do
+          wrapped.to receive(:foo) { :curly } do
+            :do_end
+          end
+
+          expect(receiver.foo).to eq(:curly)
+        end
+
+        it 'does not support other matchers', :unless => options.include?(:allow_other_matchers) do
+          expect {
+            wrapped.to eq(3)
+          }.to raise_error(UnsupportedMatcherError)
+        end
+
+        it 'does not get confused by messages being passed as strings and symbols' do
+          wrapped.to receive(:foo).with(1) { :a }
+          wrapped.to receive("foo").with(2) { :b }
+
+          expect(receiver.foo(1)).to eq(:a)
+          expect(receiver.foo(2)).to eq(:b)
+        end
+
+        it 'allows do...end blocks to be passed to the fluent interface methods without getting a warning' do
+          expect(RSpec).not_to receive(:warning)
+
+          wrapped.to receive(:foo).with(1) do
+            :a
+          end
+
+          expect(receiver.foo(1)).to eq(:a)
+        end
+
+        it 'makes { } blocks trump do...end blocks when passed to a fluent interface method' do
+          wrapped.to receive(:foo).with(1) { :curly } do
+            :do_end
+          end
+
+          expect(receiver.foo(1)).to eq(:curly)
+        end
+      end
+
+      shared_examples "an expect syntax allowance" do |*options|
+        it_behaves_like "a receive matcher", *options
+
+        it 'does not expect the message to be received' do
+          wrapped.to receive(:foo)
+          expect { verify_all }.not_to raise_error
+        end
+      end
+
+      shared_examples "an expect syntax negative allowance" do
+        it 'is disabled since this expression is confusing' do
+          expect {
+            wrapped.not_to receive(:foo)
+          }.to raise_error(/not_to receive` is not supported/)
+
+          expect {
+            wrapped.to_not receive(:foo)
+          }.to raise_error(/to_not receive` is not supported/)
+        end
+      end
+
+      shared_examples "an expect syntax expectation" do |*options|
+        it_behaves_like "a receive matcher", *options
+
+        it 'sets up a message expectation that passes if the message is received' do
+          wrapped.to receive(:foo)
+          receiver.foo
+          verify_all
+        end
+
+        it 'sets up a message expectation that fails if the message is not received' do
+          wrapped.to receive(:foo)
+
+          expect {
+            verify_all
+          }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+        it "reports the line number of expectation of unreceived message", :pending => options.include?(:does_not_report_line_num) do
+          expected_error_line = __LINE__; wrapped.to receive(:foo)
+
+          expect {
+            verify_all
+          }.to raise_error { |e|
+            expect(e.backtrace.first).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
+          }
+        end
+
+        it "provides a useful matcher description" do
+          matcher = receive(:foo).with(:bar).once
+          wrapped.to matcher
+          receiver.foo(:bar)
+
+          expect(matcher.description).to start_with("receive foo")
+        end
+      end
+
+      shared_examples "an expect syntax negative expectation" do
+        it 'sets up a negaive message expectation that passes if the message is not received' do
+          wrapped.not_to receive(:foo)
+          verify_all
+        end
+
+        it 'sets up a negative message expectation that fails if the message is received' do
+          wrapped.not_to receive(:foo)
+
+          expect {
+            receiver.foo
+          }.to raise_error(/expected: 0 times.*received: 1 time/m)
+        end
+
+        it 'supports `to_not` as an alias for `not_to`' do
+          wrapped.to_not receive(:foo)
+
+          expect {
+            receiver.foo
+          }.to raise_error(/expected: 0 times.*received: 1 time/m)
+        end
+
+        it 'allows the caller to constrain the received arguments' do
+          wrapped.not_to receive(:foo).with(:a)
+          def receiver.method_missing(*a); end # a poor man's stub...
+
+          expect {
+            receiver.foo(:b)
+          }.not_to raise_error
+
+          expect {
+            receiver.foo(:a)
+          }.to raise_error(/expected: 0 times.*received: 1 time/m)
+        end
+
+        it 'prevents confusing double-negative expressions involving `never`' do
+          expect {
+            wrapped.not_to receive(:foo).never
+          }.to raise_error(/trying to negate it again/)
+
+          expect {
+            wrapped.to_not receive(:foo).never
+          }.to raise_error(/trying to negate it again/)
+        end
+      end
+
+      shared_examples "resets partial mocks cleanly" do
+        let(:klass)  { Struct.new(:foo) }
+        let(:object) { klass.new :bar }
+
+        it "removes the method double" do
+          target.to receive(:foo).and_return(:baz)
+          expect { reset object }.to change { object.foo }.from(:baz).to(:bar)
+        end
+
+        context "on a frozen object" do
+          it "warns about being unable to remove the method double" do
+            target.to receive(:foo).and_return(:baz)
+            expect_warning_without_call_site(/rspec-mocks was unable to restore the original `foo` method on #{object.inspect}/)
+            object.freeze
+            reset object
+          end
+
+          it "includes the spec location in the warning" do
+            line = __LINE__ - 1
+            target.to receive(:foo).and_return(:baz)
+            expect_warning_without_call_site(/#{RSpec::Core::Metadata.relative_path(__FILE__)}:#{line}/)
+            object.freeze
+            reset object
+          end
+        end
+      end
+
+      shared_examples "resets partial mocks of any instance cleanly" do
+        let(:klass)  { Struct.new(:foo) }
+        let(:object) { klass.new :bar }
+
+        it "removes the method double" do
+          target.to receive(:foo).and_return(:baz)
+          expect {
+            verify_all
+          }.to change { object.foo }.from(:baz).to(:bar)
+        end
+      end
+
+      describe "allow(...).to receive" do
+        it_behaves_like "an expect syntax allowance" do
+          let(:receiver) { double }
+          let(:wrapped)  { allow(receiver) }
+        end
+        it_behaves_like "resets partial mocks cleanly" do
+          let(:target) { allow(object) }
+        end
+      end
+
+      describe "allow(...).not_to receive" do
+        it_behaves_like "an expect syntax negative allowance" do
+          let(:wrapped) { allow(double) }
+        end
+      end
+
+      describe "allow_any_instance_of(...).to receive" do
+        it_behaves_like "an expect syntax allowance" do
+          let(:klass)    { Class.new }
+          let(:wrapped)  { allow_any_instance_of(klass) }
+          let(:receiver) { klass.new }
+        end
+
+        it_behaves_like "resets partial mocks of any instance cleanly" do
+          let(:target) { allow_any_instance_of(klass) }
+        end
+      end
+
+      describe "allow_any_instance_of(...).not_to receive" do
+        it_behaves_like "an expect syntax negative allowance" do
+          let(:wrapped) { allow_any_instance_of(Class.new) }
+        end
+      end
+
+      describe "expect(...).to receive" do
+        it_behaves_like "an expect syntax expectation", :allow_other_matchers do
+          let(:receiver) { double }
+          let(:wrapped)  { expect(receiver) }
+
+          it 'sets up a message expectation that formats argument matchers correctly' do
+            wrapped.to receive(:foo).with an_instance_of Fixnum
+            expect { verify_all }.to(
+              raise_error(/expected: 1 time with arguments: \(an instance of Fixnum\)\n\s+received: 0 times$/)
+            )
+          end
+        end
+        it_behaves_like "resets partial mocks cleanly" do
+          let(:target) { expect(object) }
+        end
+
+        context "ordered with receive counts" do
+          let(:dbl) { double(:one => 1, :two => 2) }
+
+          it "passes with exact receive counts when the ordering is correct" do
+            expect(dbl).to receive(:one).twice.ordered
+            expect(dbl).to receive(:two).once.ordered
+
+            dbl.one
+            dbl.one
+            dbl.two
+          end
+
+          it "fails with exact receive counts when the ordering is incorrect" do
+            expect {
+              expect(dbl).to receive(:one).twice.ordered
+              expect(dbl).to receive(:two).once.ordered
+
+              dbl.one
+              dbl.two
+              dbl.one
+            }.to raise_error(/out of order/)
+
+            reset_all
+          end
+
+          it "passes with at least when the ordering is correct" do
+            expect(dbl).to receive(:one).at_least(2).times.ordered
+            expect(dbl).to receive(:two).once.ordered
+
+            dbl.one
+            dbl.one
+            dbl.one
+            dbl.two
+          end
+
+          it "fails with at least when the ordering is incorrect", :ordered_and_vauge_counts_unsupported do
+            expect {
+              expect(dbl).to receive(:one).at_least(2).times.ordered
+              expect(dbl).to receive(:two).once.ordered
+
+              dbl.one
+              dbl.two
+            }.to raise_error
+
+            reset_all
+          end
+
+          it "passes with at most when the ordering is correct" do
+            expect(dbl).to receive(:one).at_most(2).times.ordered
+            expect(dbl).to receive(:two).once.ordered
+
+            dbl.one
+            dbl.two
+          end
+
+          it "fails with at most when the ordering is incorrect", :ordered_and_vauge_counts_unsupported do
+            expect {
+              expect(dbl).to receive(:one).at_most(2).times.ordered
+              expect(dbl).to receive(:two).once.ordered
+
+              dbl.one
+              dbl.one
+              dbl.one
+              dbl.two
+            }.to raise_error
+
+            reset_all
+          end
+        end
+      end
+
+      describe "expect_any_instance_of(...).to receive" do
+        it_behaves_like "an expect syntax expectation", :does_not_report_line_num do
+          let(:klass)    { Class.new }
+          let(:wrapped)  { expect_any_instance_of(klass) }
+          let(:receiver) { klass.new }
+
+          it 'sets up a message expectation that formats argument matchers correctly' do
+            wrapped.to receive(:foo).with an_instance_of Fixnum
+            expect { verify_all }.to raise_error(/should have received the following message\(s\) but didn't/)
+          end
+        end
+        it_behaves_like "resets partial mocks of any instance cleanly" do
+          let(:target) { expect_any_instance_of(klass) }
+        end
+      end
+
+      describe "expect(...).not_to receive" do
+        it_behaves_like "an expect syntax negative expectation" do
+          let(:receiver) { double }
+          let(:wrapped)  { expect(receiver) }
+        end
+      end
+
+      describe "expect_any_instance_of(...).not_to receive" do
+        it_behaves_like "an expect syntax negative expectation" do
+          let(:klass)    { Class.new }
+          let(:wrapped)  { expect_any_instance_of(klass) }
+          let(:receiver) { klass.new }
+        end
+      end
+
+      it 'has a description before being matched' do
+        matcher = receive(:foo)
+        expect(matcher.description).to eq("receive foo")
+      end
+
+      shared_examples "using rspec-mocks in another test framework" do
+        it 'can use the `expect` syntax' do
+          dbl = double
+
+          framework.new.instance_exec do
+            expect(dbl).to receive(:foo).and_return(3)
+          end
+
+          expect(dbl.foo).to eq(3)
+        end
+
+        it 'expects the method to be called when `expect` is used' do
+          dbl = double
+
+          framework.new.instance_exec do
+            expect(dbl).to receive(:foo)
+          end
+
+          expect { verify dbl }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+        it 'supports `expect(...).not_to receive`' do
+          dbl = double
+
+          framework.new.instance_exec do
+            expect(dbl).not_to receive(:foo)
+          end
+
+          expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+        it 'supports `expect(...).to_not receive`' do
+          dbl = double
+
+          framework.new.instance_exec do
+            expect(dbl).to_not receive(:foo)
+          end
+
+          expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+      end
+
+      context "when used in a test framework without rspec-expectations" do
+        let(:framework) do
+          Class.new do
+            include RSpec::Mocks::ExampleMethods
+
+            def eq(value)
+              double("MyMatcher")
+            end
+          end
+        end
+
+        it_behaves_like "using rspec-mocks in another test framework"
+
+        it 'cannot use `expect` with another matcher' do
+          expect {
+            framework.new.instance_exec do
+              expect(3).to eq(3)
+            end
+          }.to raise_error(/only the `receive` or `receive_messages` matchers are supported with `expect\(...\).to`/)
+        end
+
+        it 'can toggle the available syntax' do
+          expect(framework.new).to respond_to(:expect)
+          RSpec::Mocks.configuration.syntax = :should
+          expect(framework.new).not_to respond_to(:expect)
+          RSpec::Mocks.configuration.syntax = :expect
+          expect(framework.new).to respond_to(:expect)
+        end
+
+        after { RSpec::Mocks.configuration.syntax = :expect }
+      end
+
+      context "when rspec-expectations is included in the test framework first" do
+        before do
+          # the examples here assume `expect` is define in RSpec::Matchers...
+          expect(RSpec::Matchers.method_defined?(:expect)).to be_truthy
+        end
+
+        let(:framework) do
+          Class.new do
+            include RSpec::Matchers
+            include RSpec::Mocks::ExampleMethods
+          end
+        end
+
+        it_behaves_like "using rspec-mocks in another test framework"
+
+        it 'can use `expect` with any matcher' do
+          framework.new.instance_exec do
+            expect(3).to eq(3)
+          end
+        end
+      end
+
+      context "when rspec-expectations is included in the test framework last" do
+        before do
+          # the examples here assume `expect` is define in RSpec::Matchers...
+          expect(RSpec::Matchers.method_defined?(:expect)).to be_truthy
+        end
+
+        let(:framework) do
+          Class.new do
+            include RSpec::Mocks::ExampleMethods
+            include RSpec::Matchers
+          end
+        end
+
+        it_behaves_like "using rspec-mocks in another test framework"
+
+        it 'can use `expect` with any matcher' do
+          framework.new.instance_exec do
+            expect(3).to eq(3)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/methods_spec.rb b/rspec-mocks/spec/rspec/mocks/methods_spec.rb
new file mode 100644
index 0000000..09cb1dd
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/methods_spec.rb
@@ -0,0 +1,24 @@
+module RSpec
+  module Mocks
+    RSpec.describe "Methods added to every object" do
+      include_context "with syntax", :expect
+
+      def added_methods
+        host = Class.new
+        orig_instance_methods = host.instance_methods
+        Syntax.enable_should(host)
+        (host.instance_methods - orig_instance_methods).map(&:to_sym)
+      end
+
+      it 'limits the number of methods that get added to all objects' do
+        # If really necessary, you can add to this list, but long term,
+        # we are hoping to cut down on the number of methods added to all objects
+        expect(added_methods).to match_array([
+          :as_null_object, :null_object?,
+          :received_message?, :should_not_receive, :should_receive,
+          :stub, :stub_chain, :unstub
+        ])
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/mock_expectation_error_spec.rb b/rspec-mocks/spec/rspec/mocks/mock_expectation_error_spec.rb
new file mode 100644
index 0000000..49211d5
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/mock_expectation_error_spec.rb
@@ -0,0 +1,20 @@
+module RSpec
+  module Mocks
+    RSpec.describe 'MockExpectationError' do
+
+      class Foo
+        def self.foo
+          bar
+        rescue StandardError
+        end
+      end
+
+      it 'is not caught by StandardError rescue blocks' do
+        expect(Foo).not_to receive(:bar)
+        expect {
+          Foo.foo
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/mock_ordering_spec.rb b/rspec-mocks/spec/rspec/mocks/mock_ordering_spec.rb
new file mode 100644
index 0000000..57821ca
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/mock_ordering_spec.rb
@@ -0,0 +1,112 @@
+module RSpec
+  module Mocks
+
+    RSpec.describe "ordering" do
+      before { @double = double("test double") }
+      after  { reset @double }
+
+      it "passes when messages are received in order" do
+        expect(@double).to receive(:one).ordered
+        expect(@double).to receive(:two).ordered
+        expect(@double).to receive(:three).ordered
+        @double.one
+        @double.two
+        @double.three
+      end
+
+      it "passes when messages are received in order" do
+        allow(@double).to receive(:something)
+        expect(@double).to receive(:one).ordered
+        expect(@double).to receive(:two).ordered
+        expect(@double).to receive(:three).at_least(:once).ordered
+        @double.one
+        @double.two
+        @double.three
+        @double.three
+      end
+
+      it "passes when messages are received in order across objects" do
+        a = double("a")
+        b = double("b")
+        expect(a).to receive(:one).ordered
+        expect(b).to receive(:two).ordered
+        expect(a).to receive(:three).ordered
+        a.one
+        b.two
+        a.three
+      end
+
+      it "fails when messages are received out of order (2nd message 1st)" do
+        expect(@double).to receive(:one).ordered
+        expect(@double).to receive(:two).ordered
+        expect {
+          @double.two
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :two out of order")
+      end
+
+      it "fails when messages are received out of order (3rd message 1st)" do
+        expect(@double).to receive(:one).ordered
+        expect(@double).to receive(:two).ordered
+        expect(@double).to receive(:three).ordered
+        @double.one
+        expect {
+          @double.three
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :three out of order")
+      end
+
+      it "fails when messages are received out of order (3rd message 2nd)" do
+        expect(@double).to receive(:one).ordered
+        expect(@double).to receive(:two).ordered
+        expect(@double).to receive(:three).ordered
+        @double.one
+        expect {
+          @double.three
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :three out of order")
+      end
+
+      it "fails when messages are out of order across objects" do
+        a = double("test double")
+        b = double("another test double")
+        expect(a).to receive(:one).ordered
+        expect(b).to receive(:two).ordered
+        expect(a).to receive(:three).ordered
+        a.one
+        expect {
+          a.three
+        }.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :three out of order")
+        reset a
+        reset b
+      end
+
+      it "ignores order of non ordered messages" do
+        expect(@double).to receive(:ignored_0)
+        expect(@double).to receive(:ordered_1).ordered
+        expect(@double).to receive(:ignored_1)
+        expect(@double).to receive(:ordered_2).ordered
+        expect(@double).to receive(:ignored_2)
+        expect(@double).to receive(:ignored_3)
+        expect(@double).to receive(:ordered_3).ordered
+        expect(@double).to receive(:ignored_4)
+        @double.ignored_3
+        @double.ordered_1
+        @double.ignored_0
+        @double.ordered_2
+        @double.ignored_4
+        @double.ignored_2
+        @double.ordered_3
+        @double.ignored_1
+        verify @double
+      end
+
+      it "supports duplicate messages" do
+        expect(@double).to receive(:a).ordered
+        expect(@double).to receive(:b).ordered
+        expect(@double).to receive(:a).ordered
+
+        @double.a
+        @double.b
+        @double.a
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/modifying_invoked_expectations_spec.rb b/rspec-mocks/spec/rspec/mocks/modifying_invoked_expectations_spec.rb
new file mode 100644
index 0000000..988608e
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/modifying_invoked_expectations_spec.rb
@@ -0,0 +1,27 @@
+require "spec_helper"
+
+RSpec.describe "Modifying invoked expectations" do
+  shared_examples_for "a customization on an invoked expectation" do |customization_method, *args|
+    it "raises when the #{customization_method} method is called, indicating the expectation has already been invoked" do
+      dbl = double
+      msg_expectation = expect(dbl).to receive(:foo)
+      expect(dbl.foo).to eq(nil)
+
+      expect {
+        msg_expectation.__send__(customization_method, *args)
+      }.to raise_error(
+        RSpec::Mocks::MockExpectationAlreadyInvokedError,
+        a_string_including(dbl.inspect, "foo", customization_method.to_s)
+      )
+    end
+  end
+
+  it_behaves_like "a customization on an invoked expectation", :with, :some_arg
+  it_behaves_like "a customization on an invoked expectation", :and_return, 1
+  it_behaves_like "a customization on an invoked expectation", :and_raise, "boom"
+  it_behaves_like "a customization on an invoked expectation", :and_throw, :symbol
+  it_behaves_like "a customization on an invoked expectation", :and_yield, 1
+  it_behaves_like "a customization on an invoked expectation", :exactly, :once
+  it_behaves_like "a customization on an invoked expectation", :at_least, :once
+  it_behaves_like "a customization on an invoked expectation", :at_most, :once
+end
diff --git a/rspec-mocks/spec/rspec/mocks/multiple_return_value_spec.rb b/rspec-mocks/spec/rspec/mocks/multiple_return_value_spec.rb
new file mode 100644
index 0000000..6fc86f1
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/multiple_return_value_spec.rb
@@ -0,0 +1,130 @@
+module RSpec
+  module Mocks
+    RSpec.describe "a double stubbed with multiple return values" do
+      let(:a_double) { double }
+
+      before do
+        allow(a_double).to receive(:foo).and_return(:val_1, nil)
+      end
+
+      it 'can still set a message expectation with a single return value' do
+        expect(a_double).to receive(:foo).once.and_return(:val_1)
+        expect(a_double.foo).to eq(:val_1)
+      end
+    end
+
+    RSpec.describe "a message expectation with multiple return values and no specified count" do
+      before(:each) do
+        @double = double
+        @return_values = [1,2,3]
+        expect(@double).to receive(:do_something).and_return(@return_values[0], at return_values[1], at return_values[2])
+      end
+
+      it "returns values in order" do
+        expect(@double.do_something).to eq @return_values[0]
+        expect(@double.do_something).to eq @return_values[1]
+        expect(@double.do_something).to eq @return_values[2]
+        verify @double
+      end
+
+      it "falls back to a previously stubbed value" do
+        allow(@double).to receive_messages :do_something => :stub_result
+        expect(@double.do_something).to eq @return_values[0]
+        expect(@double.do_something).to eq @return_values[1]
+        expect(@double.do_something).to eq @return_values[2]
+        expect(@double.do_something).to eq :stub_result
+      end
+
+      it "fails when there are too few calls (if there is no stub)" do
+        @double.do_something
+        @double.do_something
+        expect { verify @double }.to raise_error
+      end
+
+      it "fails when there are too many calls (if there is no stub)" do
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        expect { verify @double }.to raise_error
+      end
+    end
+
+    RSpec.describe "a message expectation with multiple return values with a specified count equal to the number of values" do
+      before(:each) do
+        @double = double
+        @return_values = [1,2,3]
+        expect(@double).to receive(:do_something).exactly(3).times.and_return(@return_values[0], @return_values[1], @return_values[2])
+      end
+
+      it "returns values in order to consecutive calls" do
+        expect(@double.do_something).to eq @return_values[0]
+        expect(@double.do_something).to eq @return_values[1]
+        expect(@double.do_something).to eq @return_values[2]
+        verify @double
+      end
+    end
+
+    RSpec.describe "a message expectation with multiple return values specifying at_least less than the number of values" do
+      before(:each) do
+        @double = double
+        expect(@double).to receive(:do_something).at_least(:twice).with(no_args).and_return(11, 22)
+      end
+
+      it "uses the last return value for subsequent calls" do
+        expect(@double.do_something).to equal(11)
+        expect(@double.do_something).to equal(22)
+        expect(@double.do_something).to equal(22)
+        verify @double
+      end
+
+      it "fails when called less than the specified number" do
+        expect(@double.do_something).to equal(11)
+        expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      context "when method is stubbed too" do
+        before { allow(@double).to receive(:do_something).and_return :stub_result }
+
+        it "uses the last value for subsequent calls" do
+          expect(@double.do_something).to equal(11)
+          expect(@double.do_something).to equal(22)
+          expect(@double.do_something).to equal(22)
+          verify @double
+        end
+
+        it "fails when called less than the specified number" do
+          expect(@double.do_something).to equal(11)
+          expect { verify @double }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+      end
+    end
+
+    RSpec.describe "a message expectation with multiple return values with a specified count larger than the number of values" do
+      before(:each) do
+        @double = RSpec::Mocks::Double.new("double")
+        expect(@double).to receive(:do_something).exactly(3).times.and_return(11, 22)
+      end
+
+      it "uses the last return value for subsequent calls" do
+        expect(@double.do_something).to equal(11)
+        expect(@double.do_something).to equal(22)
+        expect(@double.do_something).to equal(22)
+        verify @double
+      end
+
+      it "fails when called less than the specified number" do
+        @double.do_something
+        @double.do_something
+        expect { verify @double }.to raise_error
+      end
+
+      it "fails fast when called greater than the specified number" do
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        expect { @double.do_something }.to raise_error
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/mutate_const_spec.rb b/rspec-mocks/spec/rspec/mocks/mutate_const_spec.rb
new file mode 100644
index 0000000..bb9bb7a
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/mutate_const_spec.rb
@@ -0,0 +1,584 @@
+TOP_LEVEL_VALUE_CONST = 7
+
+class TestClass
+  M = :m
+  N = :n
+
+  class Nested
+    class NestedEvenMore
+    end
+  end
+end
+
+class TestClassThatDefinesSend
+  C = :c
+
+  def self.send
+  end
+end
+
+class TestSubClass < TestClass
+  P = :p
+end
+
+module RSpec
+  module Mocks
+    RSpec.describe "Constant Mutating" do
+      include RSpec::Support::RecursiveConstMethods
+
+      def reset_rspec_mocks
+        ::RSpec::Mocks.space.reset_all
+      end
+
+      shared_context "constant example methods" do |const_name|
+        define_method :const do
+          recursive_const_get(const_name)
+        end
+
+        define_method :parent_const do
+          recursive_const_get("Object::" + const_name.sub(/(::)?[^:]+\z/, ''))
+        end
+
+        define_method :last_const_part do
+          const_name.split('::').last
+        end
+      end
+
+      shared_examples "loaded constant stubbing" do |const_name|
+        include_context "constant example methods", const_name
+
+        let!(:original_const_value) { const }
+        after { change_const_value_to(original_const_value) }
+
+        def change_const_value_to(value)
+          parent_const.__send__(:remove_const, last_const_part)
+          parent_const.const_set(last_const_part, value)
+        end
+
+        it 'allows it to be stubbed' do
+          expect(const).not_to eq(7)
+          stub_const(const_name, 7)
+          expect(const).to eq(7)
+        end
+
+        it 'resets it to its original value when rspec clears its mocks' do
+          original_value = const
+          expect(original_value).not_to eq(:a)
+          stub_const(const_name, :a)
+          reset_rspec_mocks
+          expect(const).to be(original_value)
+        end
+
+        it 'returns the stubbed value' do
+          expect(stub_const(const_name, 7)).to eq(7)
+        end
+      end
+
+      shared_examples "loaded constant hiding" do |const_name|
+        before do
+          expect(recursive_const_defined?(const_name)).to be_truthy
+        end
+
+        it 'allows it to be hidden' do
+          hide_const(const_name)
+          expect(recursive_const_defined?(const_name)).to be_falsey
+        end
+
+        it 'resets the constant when rspec clear its mocks' do
+          hide_const(const_name)
+          reset_rspec_mocks
+          expect(recursive_const_defined?(const_name)).to be_truthy
+        end
+
+        it 'returns nil' do
+          expect(hide_const(const_name)).to be_nil
+        end
+      end
+
+      shared_examples "unloaded constant stubbing" do |const_name|
+        include_context "constant example methods", const_name
+
+        before do
+          expect(recursive_const_defined?(const_name)).to be_falsey
+        end
+
+        it 'allows it to be stubbed' do
+          stub_const(const_name, 7)
+          expect(const).to eq(7)
+        end
+
+        it 'removes the constant when rspec clears its mocks' do
+          stub_const(const_name, 7)
+          reset_rspec_mocks
+          expect(recursive_const_defined?(const_name)).to be_falsey
+        end
+
+        it 'returns the stubbed value' do
+          expect(stub_const(const_name, 7)).to eq(7)
+        end
+
+        it 'ignores the :transfer_nested_constants option if passed' do
+          stub = Module.new
+          stub_const(const_name, stub, :transfer_nested_constants => true)
+          expect(stub.constants).to eq([])
+        end
+      end
+
+      shared_examples "unloaded constant hiding" do |const_name|
+        include_context "constant example methods", const_name
+
+        before do
+          expect(recursive_const_defined?(const_name)).to be_falsey
+        end
+
+        it 'allows it to be hidden, though the operation has no effect' do
+          hide_const(const_name)
+          expect(recursive_const_defined?(const_name)).to be_falsey
+        end
+
+        it 'remains undefined after rspec clears its mocks' do
+          hide_const(const_name)
+          reset_rspec_mocks
+          expect(recursive_const_defined?(const_name)).to be_falsey
+        end
+
+        it 'returns nil' do
+          expect(hide_const(const_name)).to be_nil
+        end
+      end
+
+      describe "#hide_const" do
+        context "for a loaded constant nested in a module that redefines `send`" do
+          it_behaves_like "loaded constant hiding", "TestClassThatDefinesSend::C"
+        end
+
+
+        context 'for a loaded nested constant' do
+          it_behaves_like "loaded constant hiding", "TestClass::Nested"
+        end
+
+        context 'for a loaded constant prefixed with ::' do
+          it_behaves_like 'loaded constant hiding', "::TestClass"
+        end
+
+        context 'for an unloaded constant with nested name that matches a top-level constant' do
+          it_behaves_like "unloaded constant hiding", "TestClass::Hash"
+
+          it 'does not hide the top-level constant' do
+            top_level_hash = ::Hash
+
+            hide_const("TestClass::Hash")
+            expect(::Hash).to equal(top_level_hash)
+          end
+
+          it 'does not affect the ability to access the top-level constant from nested contexts', :silence_warnings do
+            top_level_hash = ::Hash
+
+            hide_const("TestClass::Hash")
+            expect(TestClass::Hash).to equal(top_level_hash)
+          end
+        end
+
+        context 'for a loaded deeply nested constant' do
+          it_behaves_like "loaded constant hiding", "TestClass::Nested::NestedEvenMore"
+        end
+
+        context 'for an unloaded unnested constant' do
+          it_behaves_like "unloaded constant hiding", "X"
+        end
+
+        context 'for an unloaded nested constant' do
+          it_behaves_like "unloaded constant hiding", "X::Y"
+        end
+
+        it 'can be hidden multiple times but still restores the original value properly' do
+          orig_value = TestClass
+          hide_const("TestClass")
+          hide_const("TestClass")
+
+          reset_rspec_mocks
+          expect(TestClass).to be(orig_value)
+        end
+
+        it 'allows a constant to be hidden, then stubbed, restoring it to its original value properly' do
+          orig_value = TOP_LEVEL_VALUE_CONST
+
+          hide_const("TOP_LEVEL_VALUE_CONST")
+          expect(recursive_const_defined?("TOP_LEVEL_VALUE_CONST")).to be_falsey
+
+          stub_const("TOP_LEVEL_VALUE_CONST", 12345)
+          expect(TOP_LEVEL_VALUE_CONST).to eq 12345
+
+          reset_rspec_mocks
+          expect(TOP_LEVEL_VALUE_CONST).to eq orig_value
+        end
+      end
+
+      describe "#stub_const" do
+        context "for a loaded constant nested in a module that redefines `send`" do
+          it_behaves_like "loaded constant stubbing", "TestClassThatDefinesSend::C"
+        end
+
+        context 'for a loaded unnested constant' do
+          it_behaves_like "loaded constant stubbing", "TestClass"
+
+          it 'can be stubbed multiple times but still restores the original value properly' do
+            orig_value = TestClass
+            stub1, stub2 = Module.new, Module.new
+            stub_const("TestClass", stub1)
+            stub_const("TestClass", stub2)
+
+            reset_rspec_mocks
+            expect(TestClass).to be(orig_value)
+          end
+
+          it 'allows nested constants to be transferred to a stub module' do
+            tc_nested = TestClass::Nested
+            stub = Module.new
+            stub_const("TestClass", stub, :transfer_nested_constants => true)
+            expect(stub::M).to eq(:m)
+            expect(stub::N).to eq(:n)
+            expect(stub::Nested).to be(tc_nested)
+          end
+
+          it 'removes the transferred constants on reset' do
+            stub = Module.new
+            stub_const("TestClass", stub, :transfer_nested_constants => true)
+
+            expect {
+              reset_all
+            }.to change { stub.constants }.to([])
+          end
+
+          it 'does not transfer nested constants that are inherited from a superclass' do
+            stub = Module.new
+            stub_const("TestSubClass", stub, :transfer_nested_constants => true)
+            expect(stub::P).to eq(:p)
+            expect(defined?(stub::M)).to be_falsey
+            expect(defined?(stub::N)).to be_falsey
+          end
+
+          it 'raises an error when asked to transfer a nested inherited constant' do
+            original_tsc = TestSubClass
+
+            expect {
+              stub_const("TestSubClass", Module.new, :transfer_nested_constants => [:M])
+            }.to raise_error(ArgumentError)
+
+            expect(TestSubClass).to be(original_tsc)
+          end
+
+          it 'allows nested constants to be selectively transferred to a stub module' do
+            stub = Module.new
+            stub_const("TestClass", stub, :transfer_nested_constants => [:M, :N])
+            expect(stub::M).to eq(:m)
+            expect(stub::N).to eq(:n)
+            expect(defined?(stub::Nested)).to be_falsey
+          end
+
+          it 'raises an error if asked to transfer nested constants but given an object that does not support them' do
+            original_tc = TestClass
+            stub = Object.new
+            expect {
+              stub_const("TestClass", stub, :transfer_nested_constants => true)
+            }.to raise_error(ArgumentError)
+
+            expect(TestClass).to be(original_tc)
+
+            expect {
+              stub_const("TestClass", stub, :transfer_nested_constants => [:M])
+            }.to raise_error(ArgumentError)
+
+            expect(TestClass).to be(original_tc)
+          end
+
+          it 'raises an error if asked to transfer nested constants on a constant that does not support nested constants' do
+            stub = Module.new
+            expect {
+              stub_const("TOP_LEVEL_VALUE_CONST", stub, :transfer_nested_constants => true)
+            }.to raise_error(ArgumentError)
+
+            expect(TOP_LEVEL_VALUE_CONST).to eq(7)
+
+            expect {
+              stub_const("TOP_LEVEL_VALUE_CONST", stub, :transfer_nested_constants => [:M])
+            }.to raise_error(ArgumentError)
+
+            expect(TOP_LEVEL_VALUE_CONST).to eq(7)
+          end
+
+          it 'raises an error if asked to transfer a nested constant that is not defined' do
+            original_tc = TestClass
+            expect(defined?(TestClass::V)).to be_falsey
+            stub = Module.new
+
+            expect {
+              stub_const("TestClass", stub, :transfer_nested_constants => [:V])
+            }.to raise_error(/cannot transfer nested constant.*V/i)
+
+            expect(TestClass).to be(original_tc)
+          end
+
+          describe 'with global transfer_nested_constant option set' do
+            include_context "with isolated configuration"
+
+            before do
+              RSpec::Mocks.configuration.transfer_nested_constants = true
+            end
+
+            it 'allows nested constants to be transferred to a stub module' do
+              tc_nested = TestClass::Nested
+              stub = Module.new
+              stub_const("TestClass", stub)
+              expect(stub::M).to eq(:m)
+              expect(stub::N).to eq(:n)
+              expect(stub::Nested).to be(tc_nested)
+            end
+
+            context "when stubbing a constant that is not a module or a class" do
+              it 'does not attempt to transfer constants' do
+                stub_const("TOP_LEVEL_VALUE_CONST", 4)
+                expect(TOP_LEVEL_VALUE_CONST).to eq(4)
+              end
+
+              it 'still raises an error when the `:transfer_nested_constants` option is provided' do
+                expect {
+                  stub_const("TOP_LEVEL_VALUE_CONST", 4, :transfer_nested_constants => true)
+                }.to raise_error(/cannot transfer nested constant/i)
+              end
+            end
+          end
+        end
+
+        context 'for a loaded nested constant' do
+          it_behaves_like "loaded constant stubbing", "TestClass::Nested"
+        end
+
+        context 'for a loaded constant prefixed with ::' do
+          it_behaves_like 'loaded constant stubbing', "::TestClass"
+        end
+
+        context 'for an unloaded constant prefixed with ::' do
+          it_behaves_like 'unloaded constant stubbing', "::SomeUndefinedConst"
+        end
+
+        context "for an unloaded constant nested in a module that redefines `send`" do
+          it_behaves_like 'unloaded constant stubbing', "TestClassThatDefinesSend::SomeUndefinedConst"
+        end
+
+        context 'for an unloaded constant with nested name that matches a top-level constant' do
+          it_behaves_like "unloaded constant stubbing", "TestClass::Hash"
+        end
+
+        context 'for a loaded deeply nested constant' do
+          it_behaves_like "loaded constant stubbing", "TestClass::Nested::NestedEvenMore"
+        end
+
+        context 'for an unloaded unnested constant' do
+          it_behaves_like "unloaded constant stubbing", "X"
+        end
+
+        context 'for an unloaded nested constant' do
+          it_behaves_like "unloaded constant stubbing", "X::Y"
+
+          it 'removes the root constant when rspec clears its mocks' do
+            expect(defined?(X)).to be_falsey
+            stub_const("X::Y", 7)
+            reset_rspec_mocks
+            expect(defined?(X)).to be_falsey
+          end
+        end
+
+        context 'for an unloaded deeply nested constant' do
+          it_behaves_like "unloaded constant stubbing", "X::Y::Z"
+
+          it 'removes the root constant when rspec clears its mocks' do
+            expect(defined?(X)).to be_falsey
+            stub_const("X::Y::Z", 7)
+            reset_rspec_mocks
+            expect(defined?(X)).to be_falsey
+          end
+        end
+
+        context 'for an unloaded constant nested within a loaded constant' do
+          it_behaves_like "unloaded constant stubbing", "TestClass::X"
+
+          it 'removes the unloaded constant but leaves the loaded constant when rspec resets its mocks' do
+            expect(defined?(TestClass)).to be_truthy
+            expect(defined?(TestClass::X)).to be_falsey
+            stub_const("TestClass::X", 7)
+            reset_rspec_mocks
+            expect(defined?(TestClass)).to be_truthy
+            expect(defined?(TestClass::X)).to be_falsey
+          end
+
+          it 'raises a helpful error if it cannot be stubbed due to an intermediary constant that is not a module' do
+            expect(TestClass::M).to be_a(Symbol)
+            expect { stub_const("TestClass::M::X", 5) }.to raise_error(/cannot stub/i)
+          end
+        end
+
+        context 'for an unloaded constant nested deeply within a deeply nested loaded constant' do
+          it_behaves_like "unloaded constant stubbing", "TestClass::Nested::NestedEvenMore::X::Y::Z"
+
+          it 'removes the first unloaded constant but leaves the loaded nested constant when rspec resets its mocks' do
+            expect(defined?(TestClass::Nested::NestedEvenMore)).to be_truthy
+            expect(defined?(TestClass::Nested::NestedEvenMore::X)).to be_falsey
+            stub_const("TestClass::Nested::NestedEvenMore::X::Y::Z", 7)
+            reset_rspec_mocks
+            expect(defined?(TestClass::Nested::NestedEvenMore)).to be_truthy
+            expect(defined?(TestClass::Nested::NestedEvenMore::X)).to be_falsey
+          end
+        end
+      end
+    end
+
+    RSpec.describe Constant do
+      describe ".original" do
+        context 'for a previously defined unstubbed constant' do
+          let(:const) { Constant.original("TestClass::M") }
+
+          it("exposes its name")                    { expect(const.name).to eq("TestClass::M") }
+          it("indicates the name is valid")         { expect(const).to be_valid_name }
+          it("indicates it was previously defined") { expect(const).to be_previously_defined }
+          it("indicates it has not been mutated")   { expect(const).not_to be_mutated }
+          it("indicates it has not been stubbed")   { expect(const).not_to be_stubbed }
+          it("indicates it has not been hidden")    { expect(const).not_to be_hidden }
+          it("exposes its original value")          { expect(const.original_value).to eq(:m) }
+        end
+
+        context 'for a previously defined stubbed constant' do
+          before { stub_const("TestClass::M", :other) }
+          let(:const) { Constant.original("TestClass::M") }
+
+          it("exposes its name")                    { expect(const.name).to eq("TestClass::M") }
+          it("indicates the name is valid")         { expect(const).to be_valid_name }
+          it("indicates it was previously defined") { expect(const).to be_previously_defined }
+          it("indicates it has been mutated")       { expect(const).to be_mutated }
+          it("indicates it has been stubbed")       { expect(const).to be_stubbed }
+          it("indicates it has not been hidden")    { expect(const).not_to be_hidden }
+          it("exposes its original value")          { expect(const.original_value).to eq(:m) }
+        end
+
+        context 'for a previously undefined stubbed constant' do
+          before { stub_const("TestClass::Undefined", :other) }
+          let(:const) { Constant.original("TestClass::Undefined") }
+
+          it("exposes its name")                        { expect(const.name).to eq("TestClass::Undefined") }
+          it("indicates the name is valid")             { expect(const).to be_valid_name }
+          it("indicates it was not previously defined") { expect(const).not_to be_previously_defined }
+          it("indicates it has been mutated")           { expect(const).to be_mutated }
+          it("indicates it has been stubbed")           { expect(const).to be_stubbed }
+          it("indicates it has not been hidden")        { expect(const).not_to be_hidden }
+          it("returns nil for the original value")      { expect(const.original_value).to be_nil }
+        end
+
+        context 'for a previously undefined parent of a stubbed constant' do
+          before { stub_const("TestClass::UndefinedModule::Undefined", :other) }
+          let(:const) { Constant.original("TestClass::UndefinedModule") }
+
+          it("exposes its name")                        { expect(const.name).to eq("TestClass::UndefinedModule") }
+          it("indicates the name is valid")             { expect(const).to be_valid_name }
+          it("indicates it was not previously defined") { expect(const).not_to be_previously_defined }
+          it("indicates it has been mutated")           { expect(const).to be_mutated }
+          it("indicates it has been stubbed")           { expect(const).to be_stubbed }
+          it("indicates it has not been hidden")        { expect(const).not_to be_hidden }
+          it("returns nil for the original value")      { expect(const.original_value).to be_nil }
+        end
+
+        context 'for a previously undefined unstubbed constant' do
+          let(:const) { Constant.original("TestClass::Undefined") }
+
+          it("exposes its name")                        { expect(const.name).to eq("TestClass::Undefined") }
+          it("indicates the name is valid")             { expect(const).to be_valid_name }
+          it("indicates it was not previously defined") { expect(const).not_to be_previously_defined }
+          it("indicates it has not been mutated")       { expect(const).not_to be_mutated }
+          it("indicates it has not been stubbed")       { expect(const).not_to be_stubbed }
+          it("indicates it has not been hidden")        { expect(const).not_to be_hidden }
+          it("returns nil for the original value")      { expect(const.original_value).to be_nil }
+        end
+
+        context 'for a previously defined constant that has been stubbed twice' do
+          before { stub_const("TestClass::M", 1) }
+          before { stub_const("TestClass::M", 2) }
+          let(:const) { Constant.original("TestClass::M") }
+
+          it("exposes its name")                    { expect(const.name).to eq("TestClass::M") }
+          it("indicates the name is valid")         { expect(const).to be_valid_name }
+          it("indicates it was previously defined") { expect(const).to be_previously_defined }
+          it("indicates it has been mutated")       { expect(const).to be_mutated }
+          it("indicates it has been stubbed")       { expect(const).to be_stubbed }
+          it("indicates it has not been hidden")    { expect(const).not_to be_hidden }
+          it("exposes its original value")          { expect(const.original_value).to eq(:m) }
+        end
+
+        context 'for a previously undefined constant that has been stubbed twice' do
+          before { stub_const("TestClass::Undefined", 1) }
+          before { stub_const("TestClass::Undefined", 2) }
+          let(:const) { Constant.original("TestClass::Undefined") }
+
+          it("exposes its name")                        { expect(const.name).to eq("TestClass::Undefined") }
+          it("indicates the name is valid")             { expect(const).to be_valid_name }
+          it("indicates it was not previously defined") { expect(const).not_to be_previously_defined }
+          it("indicates it has been mutated")           { expect(const).to be_mutated }
+          it("indicates it has been stubbed")           { expect(const).to be_stubbed }
+          it("indicates it has not been hidden")        { expect(const).not_to be_hidden }
+          it("returns nil for the original value")      { expect(const.original_value).to be_nil }
+        end
+
+        context 'for a previously undefined hidden constant' do
+          before { hide_const("SomeUndefinedConst") }
+          let(:const) { Constant.original("SomeUndefinedConst") }
+
+          it("exposes its name")                      { expect(const.name).to eq("SomeUndefinedConst") }
+          it("indicates the name is valid")           { expect(const).to be_valid_name }
+          it("indicates it was previously undefined") { expect(const).not_to be_previously_defined }
+          it("indicates it has not been mutated")     { expect(const).not_to be_mutated }
+          it("indicates it has not not been stubbed") { expect(const).not_to be_stubbed }
+          it("indicates it has not been hidden")      { expect(const).not_to be_hidden }
+          it("returns nil for the original value")    { expect(const.original_value).to be_nil }
+        end
+
+        context 'for a previously defined hidden constant' do
+          before { hide_const("TestClass::M") }
+          let(:const) { Constant.original("TestClass::M") }
+
+          it("exposes its name")                    { expect(const.name).to eq("TestClass::M") }
+          it("indicates the name is valid")         { expect(const).to be_valid_name }
+          it("indicates it was previously defined") { expect(const).to be_previously_defined }
+          it("indicates it has been mutated")       { expect(const).to be_mutated }
+          it("indicates it has not been stubbed")   { expect(const).not_to be_stubbed }
+          it("indicates it has been hidden")        { expect(const).to be_hidden }
+          it("exposes its original value")          { expect(const.original_value).to eq(:m) }
+        end
+
+        context 'for a previously defined constant that has been hidden twice' do
+          before { hide_const("TestClass::M") }
+          before { hide_const("TestClass::M") }
+          let(:const) { Constant.original("TestClass::M") }
+
+          it("exposes its name")                    { expect(const.name).to eq("TestClass::M") }
+          it("indicates the name is valid")         { expect(const).to be_valid_name }
+          it("indicates it was previously defined") { expect(const).to be_previously_defined }
+          it("indicates it has been mutated")       { expect(const).to be_mutated }
+          it("indicates it has not been stubbed")   { expect(const).not_to be_stubbed }
+          it("indicates it has been hidden")        { expect(const).to be_hidden }
+          it("exposes its original value")          { expect(const.original_value).to eq(:m) }
+        end
+
+        context "for an invalid const name (such as an anonymous module's `inspect` output)" do
+          let(:mod)   { Module.new }
+          let(:const) { Constant.original(mod.inspect) }
+
+          it("exposes the provided string as the name") { expect(const.name).to eq(mod.inspect) }
+          it("indicates the name is invalid")           { expect(const).not_to be_valid_name }
+          it("indicates it was not previously defined") { expect(const).not_to be_previously_defined }
+          it("indicates it has not been mutated")       { expect(const).not_to be_mutated }
+          it("indicates it has not been stubbed")       { expect(const).not_to be_stubbed }
+          it("indicates it has not been hidden")        { expect(const).not_to be_hidden  }
+          it("returns nil for its original value")      { expect(const.original_value).to be_nil }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/nil_expectation_warning_spec.rb b/rspec-mocks/spec/rspec/mocks/nil_expectation_warning_spec.rb
new file mode 100644
index 0000000..9e95e07
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/nil_expectation_warning_spec.rb
@@ -0,0 +1,52 @@
+module RSpec
+  module Mocks
+    RSpec.describe "an expectation set on nil" do
+      it "issues a warning with file and line number information" do
+        expected_warning = %r%An expectation of :foo was set on nil. Called from #{__FILE__}:#{__LINE__+3}(:in .+)?. Use allow_message_expectations_on_nil to disable warnings.%
+        expect(Kernel).to receive(:warn).with(expected_warning)
+
+        expect(nil).to receive(:foo)
+        nil.foo
+      end
+
+      it "issues a warning when the expectation is negative" do
+        expect(Kernel).to receive(:warn)
+
+        expect(nil).not_to receive(:foo)
+      end
+
+      it "does not issue a warning when expectations are set to be allowed" do
+        allow_message_expectations_on_nil
+        expect(Kernel).not_to receive(:warn)
+
+        expect(nil).to receive(:foo)
+        expect(nil).not_to receive(:bar)
+        nil.foo
+      end
+
+      it 'does not call #nil? on a double extra times' do
+        dbl = double
+        expect(dbl).to receive(:nil?).once.and_return(false)
+        dbl.nil?
+      end
+    end
+
+    RSpec.describe "#allow_message_expectations_on_nil" do
+      include_context "with monkey-patched marshal"
+
+      it "does not affect subsequent examples" do
+        allow_message_expectations_on_nil
+        RSpec::Mocks.teardown
+        RSpec::Mocks.setup
+        expect(Kernel).to receive(:warn)
+        expect(nil).to receive(:foo)
+        nil.foo
+      end
+
+      it 'doesnt error when marshalled' do
+        allow_message_expectations_on_nil
+        expect(Marshal.dump(nil)).to eq Marshal.dump_without_rspec_mocks(nil)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/null_object_double_spec.rb b/rspec-mocks/spec/rspec/mocks/null_object_double_spec.rb
new file mode 100644
index 0000000..09e2d68
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/null_object_double_spec.rb
@@ -0,0 +1,135 @@
+module RSpec
+  module Mocks
+    RSpec.describe "a double _not_ acting as a null object" do
+      before(:each) do
+        @double = double('non-null object')
+      end
+
+      it "says it does not respond to messages it doesn't understand" do
+        expect(@double).not_to respond_to(:foo)
+      end
+
+      it "says it responds to messages it does understand" do
+        allow(@double).to receive(:foo)
+        expect(@double).to respond_to(:foo)
+      end
+
+      it "raises an error when interpolated in a string as an integer" do
+        # Not sure why, but 1.9.2 (but not JRuby --1.9) raises a different
+        # error than 1.8.7 and 1.9.3...
+        expected_error = (RUBY_VERSION == '1.9.2' && RUBY_PLATFORM !~ /java/) ?
+                         RSpec::Mocks::MockExpectationError :
+                         TypeError
+
+        expect { "%i" % @double }.to raise_error(expected_error)
+      end
+    end
+
+    RSpec.describe "a double acting as a null object" do
+      before(:each) do
+        @double = double('null object').as_null_object
+      end
+
+      it "says it responds to everything" do
+        expect(@double).to respond_to(:any_message_it_gets)
+      end
+
+      it "allows explicit stubs" do
+        allow(@double).to receive(:foo) { "bar" }
+        expect(@double.foo).to eq("bar")
+      end
+
+      it "allows explicit expectation" do
+        expect(@double).to receive(:something)
+        @double.something
+      end
+
+      it 'returns a string from `to_str`' do
+        expect(@double.to_str).to be_a(String)
+      end
+
+      it 'continues to return self from an explicit expectation' do
+        expect(@double).to receive(:bar)
+        expect(@double.foo.bar).to be(@double)
+      end
+
+      it 'returns an explicitly stubbed value from an expectation with no implementation' do
+        allow(@double).to receive_messages(:foo => "bar")
+        expect(@double).to receive(:foo)
+        expect(@double.foo).to eq("bar")
+      end
+
+      it "fails verification when explicit exception not met" do
+        expect {
+          expect(@double).to receive(:something)
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "ignores unexpected methods" do
+        @double.random_call("a", "d", "c")
+        verify @double
+      end
+
+      it 'allows unexpected message sends using `send`' do
+        val = @double.send(:foo).send(:bar)
+        expect(val).to equal(@double)
+      end
+
+      it 'allows unexpected message sends using `send`' do
+        val = @double.__send__(:foo).__send__(:bar)
+        expect(val).to equal(@double)
+      end
+
+      it "allows expected message with different args first" do
+        expect(@double).to receive(:message).with(:expected_arg)
+        @double.message(:unexpected_arg)
+        @double.message(:expected_arg)
+      end
+
+      it "allows expected message with different args second" do
+        expect(@double).to receive(:message).with(:expected_arg)
+        @double.message(:expected_arg)
+        @double.message(:unexpected_arg)
+      end
+
+      it "can be interpolated in a string as an integer" do
+        # This form of string interpolation calls
+        # @double.to_int.to_int.to_int...etc until it gets an integer,
+        # and thus gets stuck in an infinite loop unless our double
+        # returns an int value from #to_int.
+        expect(("%i" % @double)).to eq("0")
+      end
+
+      it "does not allow null objects to be used outside of examples" do
+        RSpec::Mocks.teardown
+
+        expect { @double.some.long.message.chain }.to raise_error(RSpec::Mocks::OutsideOfExampleError)
+        expect { @double.as_null_object }.to raise_error(RSpec::Mocks::OutsideOfExampleError)
+      end
+    end
+
+    RSpec.describe "#as_null_object" do
+      it "sets the object to null_object" do
+        obj = double('anything').as_null_object
+        expect(obj).to be_null_object
+      end
+    end
+
+    RSpec.describe "#null_object?" do
+      it "defaults to false" do
+        obj = double('anything')
+        expect(obj).not_to be_null_object
+      end
+    end
+
+    RSpec.describe "when using the :expect syntax" do
+      include_context "with syntax", :expect
+
+      it 'still supports null object doubles' do
+        obj = double("foo").as_null_object
+        expect(obj.foo.bar.bazz).to be(obj)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/once_counts_spec.rb b/rspec-mocks/spec/rspec/mocks/once_counts_spec.rb
new file mode 100644
index 0000000..fd4ae01
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/once_counts_spec.rb
@@ -0,0 +1,50 @@
+module RSpec
+  module Mocks
+    RSpec.describe "#once" do
+      before(:each) do
+        @double = double
+      end
+
+      it "passes when called once" do
+        expect(@double).to receive(:do_something).once
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when called once with specified args" do
+        expect(@double).to receive(:do_something).once.with("a", "b", "c")
+        @double.do_something("a", "b", "c")
+        verify @double
+      end
+
+      it "passes when called once with unspecified args" do
+        expect(@double).to receive(:do_something).once
+        @double.do_something("a", "b", "c")
+        verify @double
+      end
+
+      it "fails when called with wrong args" do
+        expect(@double).to receive(:do_something).once.with("a", "b", "c")
+        expect {
+          @double.do_something("d", "e", "f")
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+        reset @double
+      end
+
+      it "fails fast when called twice" do
+        expect(@double).to receive(:do_something).once
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails when not called" do
+        expect(@double).to receive(:do_something).once
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/order_group_spec.rb b/rspec-mocks/spec/rspec/mocks/order_group_spec.rb
new file mode 100644
index 0000000..27a58d3
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/order_group_spec.rb
@@ -0,0 +1,26 @@
+RSpec.describe 'OrderGroup' do
+  let(:order_group) { ::RSpec::Mocks::OrderGroup.new }
+
+  describe '#consume' do
+    let(:ordered_1) { double :ordered? => true }
+    let(:ordered_2) { double :ordered? => true }
+    let(:unordered) { double :ordered? => false }
+
+    before do
+      order_group.register unordered
+      order_group.register ordered_1
+      order_group.register unordered
+      order_group.register ordered_2
+      order_group.register unordered
+      order_group.register unordered
+    end
+
+    it 'returns the first ordered? expectation' do
+      expect(order_group.consume).to eq ordered_1
+    end
+    it 'keeps returning ordered? expectation until all are returned' do
+      expectations = 3.times.map { order_group.consume }
+      expect(expectations).to eq [ordered_1, ordered_2, nil]
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/partial_double_spec.rb b/rspec-mocks/spec/rspec/mocks/partial_double_spec.rb
new file mode 100644
index 0000000..7332e8c
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/partial_double_spec.rb
@@ -0,0 +1,415 @@
+module RSpec
+  module Mocks
+    RSpec.describe "A partial double" do
+      let(:object) { Object.new }
+
+      it 'does not create an any_instance recorder when a message is allowed' do
+        expect {
+          allow(object).to receive(:foo)
+        }.not_to change { RSpec::Mocks.space.any_instance_recorders }.from({})
+      end
+
+      it "names the class in the failure message" do
+        expect(object).to receive(:foo)
+        expect do
+          verify object
+        end.to raise_error(RSpec::Mocks::MockExpectationError, /\(#<Object:.*>\).foo/)
+      end
+
+      it "names the class in the failure message when expectation is on class" do
+        expect(Object).to receive(:foo)
+        expect {
+          verify Object
+        }.to raise_error(RSpec::Mocks::MockExpectationError, /<Object \(class\)>/)
+      end
+
+      it "does not conflict with @options in the object" do
+        object.instance_exec { @options = Object.new }
+        expect(object).to receive(:blah)
+        object.blah
+      end
+
+      it 'allows `class` to be stubbed even when `any_instance` has already been used' do
+        # See https://github.com/rspec/rspec-mocks/issues/687
+        # The infinite recursion code path was only triggered when there were
+        # active any instance recorders in the current example, so we make one here.
+        allow_any_instance_of(Object).to receive(:bar).and_return(2)
+
+        expect(object.class).not_to eq(String)
+        allow(object).to receive_messages(:foo => 1, :class => String)
+
+        expect(object.foo).to eq(1)
+        expect(object.class).to eq(String)
+        expect(object.bar).to eq(2)
+      end
+
+      it "can disallow messages from being received" do
+        expect(object).not_to receive(:fuhbar)
+        expect {
+          object.fuhbar
+        }.to raise_error(
+          RSpec::Mocks::MockExpectationError,
+          /expected\: 0 times with any arguments\n    received\: 1 time/
+        )
+      end
+
+      it "can expect a message and set a return value" do
+        expect(object).to receive(:foobar).with(:test_param).and_return(1)
+        expect(object.foobar(:test_param)).to equal(1)
+      end
+
+      it "can accept a hash as a message argument" do
+        expect(object).to receive(:foobar).with(:key => "value").and_return(1)
+        expect(object.foobar(:key => "value")).to equal(1)
+      end
+
+      it "can accept an inner hash as a message argument" do
+        hash = {:a => {:key => "value"}}
+        expect(object).to receive(:foobar).with(:key => "value").and_return(1)
+        expect(object.foobar(hash[:a])).to equal(1)
+      end
+
+      it "can create a positive message expectation" do
+        expect(expect(object).to receive(:foobar)).not_to be_negative
+        object.foobar
+      end
+
+      it "verifies the method was called when expecting a message" do
+        expect(object).to receive(:foobar).with(:test_param).and_return(1)
+        expect {
+          verify object
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "can accept the string form of a message for a positive message expectation" do
+        expect(object).to receive('foobar')
+        object.foobar
+      end
+
+      it "can accept the string form of a message for a negative message expectation" do
+        expect(object).not_to receive('foobar')
+        expect {
+          object.foobar
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "uses reports nil in the error message" do
+        allow_message_expectations_on_nil
+
+        _nil = nil
+        expect(_nil).to receive(:foobar)
+        expect {
+          verify _nil
+        }.to raise_error(
+          RSpec::Mocks::MockExpectationError,
+          %Q|(nil).foobar(*(any args))\n    expected: 1 time with any arguments\n    received: 0 times with any arguments|
+        )
+      end
+
+      it "includes the class name in the error when mocking a class method that is called an extra time with the wrong args" do
+        klazz = Class.new do
+          def self.inspect
+            "MyClass"
+          end
+        end
+
+        expect(klazz).to receive(:bar).with(1)
+        klazz.bar(1)
+
+        expect {
+          klazz.bar(2)
+        }.to raise_error(RSpec::Mocks::MockExpectationError, /MyClass/)
+      end
+
+      it "shares message expectations with clone" do
+        expect(object).to receive(:foobar)
+        twin = object.clone
+        twin.foobar
+        expect{ verify twin }.not_to raise_error
+        expect{ verify object }.not_to raise_error
+      end
+
+      it "clears message expectations when `dup`ed" do
+        expect(object).to receive(:foobar)
+        duplicate = object.dup
+        expect{ duplicate.foobar }.to raise_error(NoMethodError, /foobar/)
+        expect{ verify object }.to raise_error(RSpec::Mocks::MockExpectationError, /foobar/)
+      end
+    end
+
+    RSpec.describe "Using a reopened file object as a partial mock" do
+      let(:file_1) { File.open(File.join("tmp", "file_1"), "w").tap { |f| f.sync = true } }
+      let(:file_2) { File.open(File.join("tmp", "file_2"), "w").tap { |f| f.sync = true } }
+
+      def read_file(file)
+        File.open(file.path, "r", &:read)
+      end
+
+      after do
+        file_1.close
+        file_2.close
+      end
+
+      def expect_output_warning_on_ruby_lt_2
+        if RUBY_VERSION >= '2.0'
+          yield
+        else
+          expect { yield }.to output(a_string_including(
+            "RSpec could not fully restore", file_1.inspect, "write"
+          )).to_stderr
+        end
+      end
+
+      it "allows `write` to be stubbed and reset", :unless => Support::Ruby.jruby? do
+        allow(file_1).to receive(:write)
+        file_1.reopen(file_2)
+        expect_output_warning_on_ruby_lt_2 { reset file_1 }
+
+        expect {
+          # Writing to a file that's been reopened to a 2nd file writes to both files.
+          file_1.write("foo")
+        }.to change  { read_file(file_1) }.from("").to("foo").
+          and change { read_file(file_2) }.from("").to("foo")
+      end
+    end
+
+    RSpec.describe "Using a partial mock on a proxy object", :if => defined?(::BasicObject) do
+      let(:proxy_class) do
+        Class.new(::BasicObject) do
+          def initialize(target)
+            @target = target
+          end
+
+          def proxied?
+            true
+          end
+
+          def respond_to?(name, include_all=false)
+            super || name == :proxied? || @target.respond_to?(name, include_all)
+          end
+
+          def method_missing(*a)
+            @target.send(*a)
+          end
+        end
+      end
+
+      let(:wrapped_object) { Object.new }
+      let(:proxy) { proxy_class.new(wrapped_object) }
+
+      it 'works properly' do
+        expect(proxy).to receive(:proxied?).and_return(false)
+        expect(proxy).not_to be_proxied
+      end
+
+      it 'does not confuse the proxy and the proxied object' do
+        allow(proxy).to receive(:foo).and_return(:proxy_foo)
+        allow(wrapped_object).to receive(:foo).and_return(:wrapped_foo)
+
+        expect(proxy.foo).to eq(:proxy_foo)
+        expect(wrapped_object.foo).to eq(:wrapped_foo)
+      end
+    end
+
+    RSpec.describe "Partially mocking an object that defines ==, after another mock has been defined" do
+      before(:each) do
+        double("existing mock", :foo => :foo)
+      end
+
+      let(:klass) do
+        Class.new do
+          attr_reader :val
+          def initialize(val)
+            @val = val
+          end
+
+          def ==(other)
+            @val == other.val
+          end
+        end
+      end
+
+      it "does not raise an error when stubbing the object" do
+        o = klass.new :foo
+        expect { allow(o).to receive(:bar) }.not_to raise_error
+      end
+    end
+
+    RSpec.describe "A partial class mock that has been subclassed" do
+
+      let(:klass)  { Class.new }
+      let(:subklass) { Class.new(klass) }
+
+      it "cleans up stubs during #reset to prevent leakage onto subclasses between examples" do
+        allow(klass).to receive(:new).and_return(:new_foo)
+        expect(subklass.new).to eq :new_foo
+
+        reset(klass)
+
+        expect(subklass.new).to be_a(subklass)
+      end
+
+      describe "stubbing a base class class method" do
+        before do
+          allow(klass).to receive(:find).and_return "stubbed_value"
+        end
+
+        it "returns the value for the stub on the base class" do
+          expect(klass.find).to eq "stubbed_value"
+        end
+
+        it "returns the value for the descendent class" do
+          expect(subklass.find).to eq "stubbed_value"
+        end
+      end
+    end
+
+    RSpec.describe "Method visibility when using partial mocks" do
+      let(:klass) do
+        Class.new do
+          def public_method
+            private_method
+            protected_method
+          end
+          protected
+          def protected_method; end
+          private
+          def private_method; end
+        end
+      end
+
+      let(:object) { klass.new }
+
+      it 'keeps public methods public' do
+        expect(object).to receive(:public_method)
+        expect(object.public_methods).to include_method(:public_method)
+        object.public_method
+      end
+
+      it 'keeps private methods private' do
+        expect(object).to receive(:private_method)
+        expect(object.private_methods).to include_method(:private_method)
+        object.public_method
+      end
+
+      it 'keeps protected methods protected' do
+        expect(object).to receive(:protected_method)
+        expect(object.protected_methods).to include_method(:protected_method)
+        object.public_method
+      end
+
+    end
+
+    RSpec.describe 'when verify_partial_doubles configuration option is set' do
+      include_context "with isolated configuration"
+
+      let(:klass) do
+        Class.new do
+          def implemented
+            "works"
+          end
+
+          def respond_to?(method_name, include_all=false)
+            method_name.to_s == "dynamic_method" || super
+          end
+
+          def method_missing(method_name, *args)
+            if respond_to?(method_name)
+              method_name
+            else
+              super
+            end
+          end
+
+          private
+
+          def defined_private_method
+            "works"
+          end
+        end
+      end
+
+      let(:object) { klass.new }
+
+      before do
+        RSpec::Mocks.configuration.verify_partial_doubles = true
+      end
+
+      it 'allows valid methods to be expected' do
+        expect(object).to receive(:implemented).and_call_original
+        expect(object.implemented).to eq("works")
+      end
+
+      it 'allows private methods to be expected' do
+        expect(object).to receive(:defined_private_method).and_call_original
+        expect(object.send(:defined_private_method)).to eq("works")
+      end
+
+      it 'does not allow a non-existing method to be expected' do
+        prevents { expect(object).to receive(:unimplemented) }
+      end
+
+      it 'does not allow a spy on unimplemented method' do
+        prevents(/does not implement/) {
+          expect(object).to have_received(:unimplemented)
+        }
+      end
+
+      it 'verifies arity range when matching arguments' do
+        prevents { expect(object).to receive(:implemented).with('bogus') }
+      end
+
+      it 'allows a method defined with method_missing to be expected' do
+        expect(object).to receive(:dynamic_method).with('a').and_call_original
+        expect(object.dynamic_method('a')).to eq(:dynamic_method)
+      end
+
+      it 'allows valid methods to be expected on any_instance' do
+        expect_any_instance_of(klass).to receive(:implemented)
+        object.implemented
+      end
+
+      it 'allows private methods to be expected on any_instance' do
+        expect_any_instance_of(klass).to receive(:defined_private_method).and_call_original
+        object.send(:defined_private_method)
+      end
+
+      it 'does not allow a non-existing method to be called on any_instance' do
+        prevents(/does not implement/) {
+          expect_any_instance_of(klass).to receive(:unimplemented)
+        }
+      end
+
+      it 'does not allow missing methods to be called on any_instance' do
+        # This is potentially surprising behaviour, but there is no way for us
+        # to know that this method is valid since we only have class and not an
+        # instance.
+        prevents(/does not implement/) {
+          expect_any_instance_of(klass).to receive(:dynamic_method)
+        }
+      end
+
+      it 'verifies arity range when receiving a message' do
+        allow(object).to receive(:implemented)
+        expect {
+          object.implemented('bogus')
+        }.to raise_error(
+          ArgumentError,
+          a_string_including("Wrong number of arguments. Expected 0, got 1.")
+        )
+      end
+
+      it 'allows the mock to raise an error with yield' do
+        sample_error = Class.new(StandardError)
+        expect(object).to receive(:implemented) { raise sample_error }
+        expect { object.implemented }.to raise_error(sample_error)
+      end
+
+      it 'allows stubbing and calls the stubbed implementation' do
+        allow(object).to receive(:implemented) { :value }
+        expect(object.implemented).to eq(:value)
+      end
+
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/partial_double_using_mocks_directly_spec.rb b/rspec-mocks/spec/rspec/mocks/partial_double_using_mocks_directly_spec.rb
new file mode 100644
index 0000000..605a16e
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/partial_double_using_mocks_directly_spec.rb
@@ -0,0 +1,83 @@
+module RSpec::Mocks
+  RSpec.describe "PartialDoubleUsingMocksDirectly" do
+    let(:klass) do
+      Class.new do
+        module MethodMissing
+          remove_method :method_missing rescue nil
+          def method_missing(m, *a, &b)
+            if m == :captured_by_method_missing
+              "response generated by method missing"
+            else
+              super(m, *a, &b)
+            end
+          end
+        end
+
+        extend MethodMissing
+        include MethodMissing
+
+        def existing_method
+          :original_value
+        end
+
+      end
+    end
+
+    let(:obj) { klass.new }
+
+    it "fails when expected message is not received" do
+      expect(obj).to receive(:msg)
+      expect {
+        verify obj
+      }.to raise_error(RSpec::Mocks::MockExpectationError)
+    end
+
+    it "fails when message is received with incorrect args" do
+      expect(obj).to receive(:msg).with(:correct_arg)
+      expect {
+        obj.msg(:incorrect_arg)
+      }.to raise_error(RSpec::Mocks::MockExpectationError)
+      obj.msg(:correct_arg)
+    end
+
+    it "passes when expected message is received" do
+      expect(obj).to receive(:msg)
+      obj.msg
+      verify obj
+    end
+
+    it "passes when message is received with correct args" do
+      expect(obj).to receive(:msg).with(:correct_arg)
+      obj.msg(:correct_arg)
+      verify obj
+    end
+
+    it "restores the original method if it existed" do
+      expect(obj.existing_method).to equal(:original_value)
+      expect(obj).to receive(:existing_method).and_return(:mock_value)
+      expect(obj.existing_method).to equal(:mock_value)
+      verify obj
+      expect(obj.existing_method).to equal(:original_value)
+    end
+
+    context "with an instance method handled by method_missing" do
+      it "restores the original behavior" do
+        expect(obj.captured_by_method_missing).to eq("response generated by method missing")
+        allow(obj).to receive(:captured_by_method_missing) { "foo" }
+        expect(obj.captured_by_method_missing).to eq("foo")
+        reset obj
+        expect(obj.captured_by_method_missing).to eq("response generated by method missing")
+      end
+    end
+
+    context "with a class method handled by method_missing" do
+      it "restores the original behavior" do
+        expect(klass.captured_by_method_missing).to eq("response generated by method missing")
+        allow(klass).to receive(:captured_by_method_missing) { "foo" }
+        expect(klass.captured_by_method_missing).to eq("foo")
+        reset klass
+        expect(klass.captured_by_method_missing).to eq("response generated by method missing")
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/precise_counts_spec.rb b/rspec-mocks/spec/rspec/mocks/precise_counts_spec.rb
new file mode 100644
index 0000000..77227bd
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/precise_counts_spec.rb
@@ -0,0 +1,66 @@
+module RSpec
+  module Mocks
+    RSpec.describe "PreciseCounts" do
+      before(:each) do
+        @double = double("test double")
+      end
+
+      it "fails when exactly n times method is called less than n times" do
+        expect(@double).to receive(:do_something).exactly(3).times
+        @double.do_something
+        @double.do_something
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails fast when exactly n times method is called more than n times" do
+        expect(@double).to receive(:do_something).exactly(3).times
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails when exactly n times method is never called" do
+        expect(@double).to receive(:do_something).exactly(3).times
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "passes if exactly n times method is called exactly n times" do
+        expect(@double).to receive(:do_something).exactly(3).times
+        @double.do_something
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "returns the value given by a block when the exactly once method is called" do
+        expect(@double).to receive(:to_s).exactly(:once) { "testing" }
+        expect(@double.to_s).to eq "testing"
+        verify @double
+      end
+
+      it "passes mutiple calls with different args" do
+        expect(@double).to receive(:do_something).once.with(1)
+        expect(@double).to receive(:do_something).once.with(2)
+        @double.do_something(1)
+        @double.do_something(2)
+        verify @double
+      end
+
+      it "passes multiple calls with different args and counts" do
+        expect(@double).to receive(:do_something).twice.with(1)
+        expect(@double).to receive(:do_something).once.with(2)
+        @double.do_something(1)
+        @double.do_something(2)
+        @double.do_something(1)
+        verify @double
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/serialization_spec.rb b/rspec-mocks/spec/rspec/mocks/serialization_spec.rb
new file mode 100644
index 0000000..169c529
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/serialization_spec.rb
@@ -0,0 +1,89 @@
+module RSpec
+  module Mocks
+    RSpec.describe "Serialization of mocked objects" do
+      include_context "with monkey-patched marshal"
+
+      class SerializableObject < Struct.new(:foo, :bar); end
+
+      def self.with_yaml_loaded(&block)
+        context 'with YAML loaded' do
+          module_exec(&block)
+        end
+      end
+
+      def self.without_yaml_loaded(&block)
+        context 'without YAML loaded' do
+          before do
+            # We can't really unload yaml, but we can fake it here...
+            hide_const("YAML")
+            Struct.class_exec do
+              alias __old_to_yaml to_yaml
+              undef to_yaml
+            end
+          end
+
+          module_exec(&block)
+
+          after do
+            Struct.class_exec do
+              alias to_yaml __old_to_yaml
+              undef __old_to_yaml
+            end
+          end
+        end
+      end
+
+      let(:serializable_object) { RSpec::Mocks::SerializableObject.new(7, "something") }
+
+      def set_stub
+        allow(serializable_object).to receive_messages(:bazz => 5)
+      end
+
+      shared_examples 'normal YAML serialization' do
+        it 'serializes to yaml the same with and without stubbing, using #to_yaml' do
+          expect { set_stub }.to_not change { serializable_object.to_yaml }
+        end
+
+        it 'serializes to yaml the same with and without stubbing, using YAML.dump' do
+          expect { set_stub }.to_not change { ::YAML.dump(serializable_object) }
+        end
+      end
+
+      with_yaml_loaded do
+        compiled_with_psych = begin
+          require 'psych'
+          true
+        rescue LoadError
+          false
+        end
+
+        if compiled_with_psych
+          context 'using Syck as the YAML engine' do
+            before(:each) { ::YAML::ENGINE.yamler = 'syck' }
+            around(:each) { |example| with_isolated_stderr(&example) }
+            it_behaves_like 'normal YAML serialization'
+          end if defined?(::YAML::ENGINE)
+
+          context 'using Psych as the YAML engine' do
+            before(:each) { ::YAML::ENGINE.yamler = 'psych' } if defined?(::YAML::ENGINE)
+            it_behaves_like 'normal YAML serialization'
+          end
+        else
+          it_behaves_like 'normal YAML serialization'
+        end
+      end
+
+      without_yaml_loaded do
+        it 'does not add #to_yaml to the stubbed object' do
+          expect(serializable_object).not_to respond_to(:to_yaml)
+          set_stub
+          expect(serializable_object).not_to respond_to(:to_yaml)
+        end
+      end
+
+      it 'marshals the same with and without stubbing' do
+        expect { set_stub }.to_not change { Marshal.dump(serializable_object) }
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/should_syntax_spec.rb b/rspec-mocks/spec/rspec/mocks/should_syntax_spec.rb
new file mode 100644
index 0000000..dfe7aa7
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/should_syntax_spec.rb
@@ -0,0 +1,539 @@
+require 'support/before_all_shared_example_group'
+
+RSpec.describe "Using the legacy should syntax" do
+  include_context "with syntax", [:should, :expect]
+
+  describe "#received_message?" do
+    let(:dbl) { double("double").as_null_object }
+
+    it "answers false for received_message? when no messages received" do
+      expect(dbl.received_message?(:message)).to be_falsey
+    end
+
+    it "answers true for received_message? when message received" do
+      dbl.message
+      expect(dbl.received_message?(:message)).to be_truthy
+    end
+
+    it "answers true for received_message? when message received with correct args" do
+      dbl.message 1,2,3
+      expect(dbl.received_message?(:message, 1,2,3)).to be_truthy
+    end
+
+    it "answers false for received_message? when message received with incorrect args" do
+      dbl.message 1,2,3
+      expect(dbl.received_message?(:message, 1,2)).to be_falsey
+    end
+  end
+
+  describe "#stub" do
+    it "supports options" do
+      double.stub(:foo, :expected_from => "bar")
+    end
+
+    it 'returns `nil` from all terminal actions to discourage further configuration' do
+      expect(double.stub(:foo).and_return(1)).to be_nil
+      expect(double.stub(:foo).and_raise("boom")).to be_nil
+      expect(double.stub(:foo).and_throw(:foo)).to be_nil
+    end
+
+    it 'sets up a canned response' do
+      dbl = double
+      dbl.stub(:foo).and_return(3)
+      expect(dbl.foo).to eq(3)
+    end
+
+    it 'can stub multiple messages using a hash' do
+      dbl = double
+      dbl.stub(:foo => 2, :bar => 1)
+      expect(dbl.foo).to eq(2)
+      expect(dbl.bar).to eq(1)
+    end
+
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        Object.stub(:foo)
+      end
+    end
+  end
+
+  describe "#stub_chain" do
+    it 'can stub a sequence of messages' do
+      dbl = double
+      dbl.stub_chain(:foo, :bar, :baz => 17)
+      expect(dbl.foo.bar.baz).to eq(17)
+      expect {
+        dbl.foo.baz.bar
+      }.to raise_error(RSpec::Mocks::MockExpectationError)
+    end
+
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        Object.stub_chain(:foo, :bar)
+      end
+    end
+  end
+
+  describe "#unstub" do
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        Object.unstub(:foo)
+      end
+    end
+
+    it "replaces the stubbed method with the original method" do
+      obj = Object.new
+      def obj.foo; :original; end
+      obj.stub(:foo)
+      obj.unstub(:foo)
+      expect(obj.foo).to eq :original
+    end
+
+    it "removes all stubs with the supplied method name" do
+      obj = Object.new
+      def obj.foo; :original; end
+      obj.stub(:foo).with(1)
+      obj.stub(:foo).with(2)
+      obj.unstub(:foo)
+      expect(obj.foo).to eq :original
+    end
+
+    it "does not remove any expectations with the same method name" do
+      obj = Object.new
+      def obj.foo; :original; end
+      obj.should_receive(:foo).with(3).and_return(:three)
+      obj.stub(:foo).with(1)
+      obj.stub(:foo).with(2)
+      obj.unstub(:foo)
+      expect(obj.foo(3)).to eq :three
+    end
+
+    it "restores the correct implementations when stubbed and unstubbed on a parent and child class" do
+      parent = Class.new
+      child  = Class.new(parent)
+
+      parent.stub(:new)
+      child.stub(:new)
+      parent.unstub(:new)
+      child.unstub(:new)
+
+      expect(parent.new).to be_an_instance_of parent
+      expect(child.new).to be_an_instance_of child
+    end
+
+    it "raises a MockExpectationError if the method has not been stubbed" do
+      obj = Object.new
+      expect {
+        obj.unstub(:foo)
+      }.to raise_error(RSpec::Mocks::MockExpectationError)
+    end
+  end
+
+  describe "#should_receive" do
+    it 'fails on verification if the message is not received' do
+      dbl = double
+      dbl.should_receive(:foo)
+      expect { verify_all }.to raise_error(RSpec::Mocks::MockExpectationError)
+    end
+
+    it 'does not fail on verification if the message is received' do
+      dbl = double
+      dbl.should_receive(:foo)
+      dbl.foo
+      expect { verify_all }.not_to raise_error
+    end
+
+    it 'can set a canned response' do
+      dbl = double
+      dbl.should_receive(:bar).and_return(3)
+      expect(dbl.bar).to eq(3)
+    end
+
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        Object.should_receive(:foo)
+      end
+    end
+
+    context "with an options hash" do
+      it "reports the file and line submitted with :expected_from" do
+        begin
+          mock = RSpec::Mocks::Double.new("a mock")
+          mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37")
+          verify mock
+        rescue Exception => e
+        ensure
+          expect(e.backtrace.to_s).to match(/\/path\/to\/blah.ext:37/m)
+        end
+      end
+
+      it "uses the message supplied with :message" do
+        expect {
+          m = RSpec::Mocks::Double.new("a mock")
+          m.should_receive(:message, :message => "recebi nada")
+          verify m
+        }.to raise_error("recebi nada")
+      end
+
+      it "uses the message supplied with :message after a similar stub" do
+        expect {
+          m = RSpec::Mocks::Double.new("a mock")
+          m.stub(:message)
+          m.should_receive(:message, :message => "from mock")
+          verify m
+        }.to raise_error("from mock")
+      end
+    end
+  end
+
+  describe "#should_not_receive" do
+    it "returns a negative message expectation" do
+      expect(Object.new.should_not_receive(:foobar)).to be_negative
+    end
+
+    it 'fails when the message is received' do
+      dbl = double
+      dbl.should_not_receive(:foo)
+      expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError)
+    end
+
+    it 'does not fail on verification if the message is not received' do
+      dbl = double
+      dbl.should_not_receive(:foo)
+      expect { verify_all }.not_to raise_error
+    end
+
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        Object.should_not_receive(:foo)
+      end
+    end
+  end
+
+  describe "#any_instance" do
+    let(:klass) do
+      Class.new do
+        def existing_method; :existing_method_return_value; end
+        def existing_method_with_arguments(arg_one, arg_two = nil); :existing_method_with_arguments_return_value; end
+        def another_existing_method; end
+        private
+        def private_method; :private_method_return_value; end
+      end
+    end
+
+    include_examples "fails in a before(:all) block" do
+      def use_rspec_mocks
+        Object.any_instance.should_receive(:foo)
+      end
+    end
+
+    it "adds an class to the current space" do
+      expect {
+        klass.any_instance
+      }.to change { RSpec::Mocks.space.any_instance_recorders.size }.by(1)
+    end
+
+    it 'can stub a method' do
+      klass.any_instance.stub(:foo).and_return(2)
+      expect(klass.new.foo).to eq(2)
+    end
+
+    it 'can mock a method' do
+      klass.any_instance.should_receive(:foo)
+      klass.new
+      expect { verify_all }.to raise_error(RSpec::Mocks::MockExpectationError)
+    end
+
+    it 'can get method objects for the fluent interface', :if => RUBY_VERSION.to_f > 1.8 do
+      and_return = klass.any_instance.stub(:foo).method(:and_return)
+      and_return.call(23)
+
+      expect(klass.new.foo).to eq(23)
+    end
+
+    it 'affects previously stubbed instances when stubbing a method' do
+      instance = klass.new
+      klass.any_instance.stub(:foo).and_return(2)
+      expect(instance.foo).to eq(2)
+      klass.any_instance.stub(:foo).and_return(1)
+      expect(instance.foo).to eq(1)
+    end
+
+    it 'affects previously stubbed instances when mocking a method' do
+      instance = klass.new
+      klass.any_instance.stub(:foo).and_return(2)
+      expect(instance.foo).to eq(2)
+      klass.any_instance.should_receive(:foo).and_return(1)
+      expect(instance.foo).to eq(1)
+    end
+
+    context "invocation order" do
+      describe "#stub" do
+        it "raises an error if 'stub' follows 'with'" do
+          expect { klass.any_instance.with("1").stub(:foo) }.to raise_error(NoMethodError)
+        end
+
+        it "raises an error if 'with' follows 'and_return'" do
+          expect { klass.any_instance.stub(:foo).and_return(1).with("1") }.to raise_error(NoMethodError)
+        end
+
+        it "raises an error if 'with' follows 'and_raise'" do
+          expect { klass.any_instance.stub(:foo).and_raise(1).with("1") }.to raise_error(NoMethodError)
+        end
+
+        it "raises an error if 'with' follows 'and_yield'" do
+          expect { klass.any_instance.stub(:foo).and_yield(1).with("1") }.to raise_error(NoMethodError)
+        end
+
+        context "behaves as 'every instance'" do
+          let(:super_class) { Class.new { def foo; 'bar'; end } }
+          let(:sub_class)   { Class.new(super_class) }
+
+          it 'handles `unstub` on subclasses' do
+            super_class.any_instance.stub(:foo)
+            sub_class.any_instance.stub(:foo)
+            sub_class.any_instance.unstub(:foo)
+            expect(sub_class.new.foo).to eq("bar")
+          end
+        end
+      end
+
+      describe "#stub_chain" do
+        it "raises an error if 'stub_chain' follows 'and_return'" do
+          expect { klass.any_instance.and_return("1").stub_chain(:foo, :bar) }.to raise_error(NoMethodError)
+        end
+
+        context "allows a chain of methods to be stubbed using #stub_chain" do
+          example "given symbols representing the methods" do
+            klass.any_instance.stub_chain(:one, :two, :three).and_return(:four)
+            expect(klass.new.one.two.three).to eq(:four)
+          end
+
+          example "given a hash as the last argument uses the value as the expected return value" do
+            klass.any_instance.stub_chain(:one, :two, :three => :four)
+            expect(klass.new.one.two.three).to eq(:four)
+          end
+
+          example "given a string of '.' separated method names representing the chain" do
+            klass.any_instance.stub_chain('one.two.three').and_return(:four)
+            expect(klass.new.one.two.three).to eq(:four)
+          end
+        end
+
+        it 'affects previously stubbed instances' do
+          instance = klass.new
+          dbl = double
+          klass.any_instance.stub(:foo).and_return(dbl)
+          expect(instance.foo).to eq(dbl)
+          klass.any_instance.stub_chain(:foo, :bar => 3)
+          expect(instance.foo.bar).to eq(3)
+        end
+      end
+
+      describe "#should_receive" do
+        it "raises an error if 'should_receive' follows 'with'" do
+          expect { klass.any_instance.with("1").should_receive(:foo) }.to raise_error(NoMethodError)
+        end
+      end
+
+      describe "#should_not_receive" do
+        it "fails if the method is called" do
+          klass.any_instance.should_not_receive(:existing_method)
+          expect { klass.new.existing_method }.to raise_error(RSpec::Mocks::MockExpectationError)
+        end
+
+        it "passes if no method is called" do
+          expect { klass.any_instance.should_not_receive(:existing_method) }.to_not raise_error
+        end
+
+        it "passes if only a different method is called" do
+          klass.any_instance.should_not_receive(:existing_method)
+          expect { klass.new.another_existing_method }.to_not raise_error
+        end
+
+        context "with constraints" do
+          it "fails if the method is called with the specified parameters" do
+            klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two)
+            expect {
+              klass.new.existing_method_with_arguments(:argument_one, :argument_two)
+            }.to raise_error(RSpec::Mocks::MockExpectationError)
+          end
+
+          it "passes if the method is called with different parameters" do
+            klass.any_instance.should_not_receive(:existing_method_with_arguments).with(:argument_one, :argument_two)
+            expect { klass.new.existing_method_with_arguments(:argument_three, :argument_four) }.to_not raise_error
+          end
+        end
+
+        context 'when used in combination with should_receive' do
+          it 'passes if only the expected message is received' do
+            klass.any_instance.should_receive(:foo)
+            klass.any_instance.should_not_receive(:bar)
+            klass.new.foo
+            verify_all
+          end
+        end
+
+        it "prevents confusing double-negative expressions involving `never`" do
+          expect {
+            klass.any_instance.should_not_receive(:not_expected).never
+          }.to raise_error(/trying to negate it again/)
+        end
+      end
+
+      describe "#unstub" do
+        it "replaces the stubbed method with the original method" do
+          klass.any_instance.stub(:existing_method)
+          klass.any_instance.unstub(:existing_method)
+          expect(klass.new.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes all stubs with the supplied method name" do
+          klass.any_instance.stub(:existing_method).with(1)
+          klass.any_instance.stub(:existing_method).with(2)
+          klass.any_instance.unstub(:existing_method)
+          expect(klass.new.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes stubs even if they have already been invoked" do
+          klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
+          obj = klass.new
+          obj.existing_method
+          klass.any_instance.unstub(:existing_method)
+          expect(obj.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes stubs from sub class after invokation when super class was originally stubbed" do
+          klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
+          obj = Class.new(klass).new
+          expect(obj.existing_method).to eq(:any_instance_value)
+          klass.any_instance.unstub(:existing_method)
+          expect(obj.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "removes stubs set directly on an instance" do
+          klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
+          obj = klass.new
+          obj.stub(:existing_method).and_return(:local_method)
+          klass.any_instance.unstub(:existing_method)
+          expect(obj.existing_method).to eq(:existing_method_return_value)
+        end
+
+        it "does not remove message expectations set directly on an instance" do
+          klass.any_instance.stub(:existing_method).and_return(:any_instance_value)
+          obj = klass.new
+          obj.should_receive(:existing_method).and_return(:local_method)
+          klass.any_instance.unstub(:existing_method)
+          expect(obj.existing_method).to eq(:local_method)
+        end
+
+        it "does not remove any expectations with the same method name" do
+          klass.any_instance.should_receive(:existing_method_with_arguments).with(3).and_return(:three)
+          klass.any_instance.stub(:existing_method_with_arguments).with(1)
+          klass.any_instance.stub(:existing_method_with_arguments).with(2)
+          klass.any_instance.unstub(:existing_method_with_arguments)
+          expect(klass.new.existing_method_with_arguments(3)).to eq(:three)
+        end
+
+        it "raises a MockExpectationError if the method has not been stubbed" do
+          expect {
+            klass.any_instance.unstub(:existing_method)
+          }.to raise_error(RSpec::Mocks::MockExpectationError, 'The method `existing_method` was not stubbed or was already unstubbed')
+        end
+
+        it 'does not get confused about string vs symbol usage for the message' do
+          klass.any_instance.stub(:existing_method) { :stubbed }
+          klass.any_instance.unstub("existing_method")
+          expect(klass.new.existing_method).to eq(:existing_method_return_value)
+        end
+      end
+    end
+  end
+end
+
+RSpec.context "with default syntax configuration" do
+  orig_syntax = nil
+
+  before(:all) { orig_syntax = RSpec::Mocks.configuration.syntax }
+  after(:all)  { RSpec::Mocks.configuration.syntax = orig_syntax }
+  before       { RSpec::Mocks.configuration.reset_syntaxes_to_default }
+
+  let(:expected_arguments) {
+    [
+      /Using.*without explicitly enabling/,
+      {:replacement=>"the new `:expect` syntax or explicitly enable `:should`"}
+    ]
+  }
+
+  it "it warns about should once, regardless of how many times it is called" do
+    expect(RSpec).to receive(:deprecate).with(*expected_arguments)
+    o = Object.new
+    o2 = Object.new
+    o.should_receive(:bees)
+    o2.should_receive(:bees)
+
+    o.bees
+    o2.bees
+  end
+
+  it "warns about should not once, regardless of how many times it is called" do
+    expect(RSpec).to receive(:deprecate).with(*expected_arguments)
+    o = Object.new
+    o2 = Object.new
+    o.should_not_receive(:bees)
+    o2.should_not_receive(:bees)
+  end
+
+  it "warns about stubbing once, regardless of how many times it is called" do
+    expect(RSpec).to receive(:deprecate).with(*expected_arguments)
+    o = Object.new
+    o2 = Object.new
+
+    o.stub(:faces)
+    o2.stub(:faces)
+  end
+
+  it "warns about unstubbing once, regardless of how many times it is called" do
+    expect(RSpec).to receive(:deprecate).with(/Using.*without explicitly enabling/,
+      {:replacement => "`allow(...).to_receive(...).and_call_original` or explicitly enable `:should`"})
+    o = Object.new
+    o2 = Object.new
+
+    allow(o).to receive(:faces)
+    allow(o2).to receive(:faces)
+
+    o.unstub(:faces)
+    o2.unstub(:faces)
+  end
+
+
+  it "doesn't warn about stubbing after a reset and setting should" do
+    expect(RSpec).not_to receive(:deprecate)
+    RSpec::Mocks.configuration.reset_syntaxes_to_default
+    RSpec::Mocks.configuration.syntax = :should
+    o = Object.new
+    o2 = Object.new
+    o.stub(:faces)
+    o2.stub(:faces)
+  end
+
+  it "includes the call site in the deprecation warning" do
+    obj = Object.new
+    expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
+    obj.stub(:faces)
+  end
+end
+
+RSpec.context "when the should syntax is enabled on a non-default syntax host" do
+  include_context "with the default mocks syntax"
+
+  it "continues to warn about the should syntax" do
+    my_host = Class.new
+    expect(RSpec).to receive(:deprecate)
+    RSpec::Mocks::Syntax.enable_should(my_host)
+
+    o = Object.new
+    o.should_receive(:bees)
+    o.bees
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/space_spec.rb b/rspec-mocks/spec/rspec/mocks/space_spec.rb
new file mode 100644
index 0000000..d5d8f5a
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/space_spec.rb
@@ -0,0 +1,242 @@
+
+module RSpec::Mocks
+  RSpec.describe Space do
+    let(:space) { Space.new }
+    let(:dbl_1) { Object.new }
+    let(:dbl_2) { Object.new }
+
+    describe "#verify_all" do
+      it "verifies all mocks within" do
+        verifies = []
+
+        allow(space.proxy_for(dbl_1)).to receive(:verify) { verifies << :dbl_1 }
+        allow(space.proxy_for(dbl_2)).to receive(:verify) { verifies << :dbl_2 }
+
+        space.verify_all
+
+        expect(verifies).to match_array([:dbl_1, :dbl_2])
+      end
+
+      def define_singleton_method_on_recorder_for(klass, name, &block)
+        recorder = space.any_instance_recorder_for(klass)
+        (class << recorder; self; end).send(:define_method, name, &block)
+      end
+
+      it 'verifies all any_instance recorders within' do
+        klass_1, klass_2 = Class.new, Class.new
+
+        verifies = []
+
+        # We can't `stub` a method on the recorder because it defines its own `stub`...
+        define_singleton_method_on_recorder_for(klass_1, :verify) { verifies << :klass_1 }
+        define_singleton_method_on_recorder_for(klass_2, :verify) { verifies << :klass_2 }
+
+        space.verify_all
+
+        expect(verifies).to match_array([:klass_1, :klass_2])
+      end
+
+      it 'does not reset the proxies (as that should be delayed until reset_all)' do
+        proxy = space.proxy_for(dbl_1)
+        reset = false
+        (class << proxy; self; end).__send__(:define_method, :reset) { reset = true }
+
+        space.verify_all
+        expect(reset).to eq(false)
+      end
+    end
+
+    describe "#reset_all" do
+      it "resets all mocks within" do
+        resets = []
+
+        allow(space.proxy_for(dbl_1)).to receive(:reset) { resets << :dbl_1 }
+        allow(space.proxy_for(dbl_2)).to receive(:reset) { resets << :dbl_2 }
+
+        space.reset_all
+
+        expect(resets).to match_array([:dbl_1, :dbl_2])
+      end
+    end
+
+    describe "#proxies_of(klass)" do
+      it 'returns proxies' do
+        space.proxy_for("")
+        expect(space.proxies_of(String).map(&:class)).to eq([PartialDoubleProxy])
+      end
+
+      def create_generations
+        grandparent_class = Class.new
+        parent_class      = Class.new(grandparent_class)
+        child_class       = Class.new(parent_class)
+
+        grandparent = grandparent_class.new
+        parent      = parent_class.new
+        child       = child_class.new
+
+        return grandparent, parent, child
+      end
+
+      it 'returns only the proxies whose object is an instance of the given class' do
+        grandparent, parent, child = create_generations
+
+        space.proxy_for(grandparent)
+
+        parent_proxy = space.proxy_for(parent)
+        child_proxy  = space.proxy_for(child)
+
+        expect(space.proxies_of(parent.class)).to contain_exactly(parent_proxy, child_proxy)
+      end
+
+      it 'looks in the parent space for matching proxies' do
+        _, parent, child = create_generations
+
+        parent_proxy = space.proxy_for(parent)
+        subspace     = space.new_scope
+        child_proxy  = subspace.proxy_for(child)
+
+        expect(subspace.proxies_of(parent.class)).to contain_exactly(parent_proxy, child_proxy)
+      end
+    end
+
+    it 'tracks proxies in parent and child space separately' do
+      proxy1   = space.proxy_for(Object.new)
+      subspace = space.new_scope
+      proxy2   = subspace.proxy_for(Object.new)
+
+      expect(space.proxies.values).to include(proxy1)
+      expect(space.proxies.values).not_to include(proxy2)
+
+      expect(subspace.proxies.values).to include(proxy2)
+      expect(subspace.proxies.values).not_to include(proxy1)
+    end
+
+    it "only adds an instance once" do
+      m1 = double("mock1")
+
+      expect {
+        space.ensure_registered(m1)
+      }.to change { space.proxies }
+
+      expect {
+        space.ensure_registered(m1)
+      }.not_to change { space.proxies }
+    end
+
+    [:ensure_registered, :proxy_for].each do |method|
+      describe "##{method}" do
+        define_method :get_proxy do |the_space, object|
+          the_space.__send__(method, object)
+        end
+
+        it 'returns the proxy for the given object' do
+          obj1 = Object.new
+          obj2 = Object.new
+
+          expect(get_proxy(space, obj1)).to equal(get_proxy(space, obj1))
+          expect(get_proxy(space, obj2)).to equal(get_proxy(space, obj2))
+          expect(get_proxy(space, obj1)).not_to equal(get_proxy(space, obj2))
+        end
+
+        it 'can stil return a proxy from a parent context' do
+          proxy    = get_proxy(space, Object)
+          subspace = space.new_scope
+
+          expect(get_proxy(subspace, Object)).to equal(proxy)
+        end
+
+        it "does not store a parent's proxy in the child space" do
+          get_proxy(space, Object)
+          subspace = space.new_scope
+
+          expect {
+            get_proxy(subspace, Object)
+          }.not_to change { subspace.proxies }.from({})
+        end
+      end
+    end
+
+    describe "#registered?" do
+      it 'returns true if registered in this space' do
+        space.ensure_registered(Object)
+        expect(space).to be_registered(Object)
+      end
+
+      it 'returns true if registered in a parent space' do
+        space.ensure_registered(Object)
+        expect(space.new_scope).to be_registered(Object)
+      end
+
+      it 'returns false if not registered in this or a parent space' do
+        expect(space.new_scope).not_to be_registered(Object)
+      end
+    end
+
+    describe "#constant_mutator_for" do
+      it 'returns the mutator for the given const name' do
+        the_space = RSpec::Mocks.space
+        stub_const("Foo", 3)
+        stub_const("Bar", 4)
+
+        expect(the_space.constant_mutator_for("Foo")).to equal(the_space.constant_mutator_for("Foo"))
+        expect(the_space.constant_mutator_for("Bar")).to equal(the_space.constant_mutator_for("Bar"))
+        expect(the_space.constant_mutator_for("Foo")).not_to equal(the_space.constant_mutator_for("Bar"))
+      end
+
+      it 'can stil return a mutator from a parent context' do
+        the_space = RSpec::Mocks.space
+
+        stub_const("Foo", 3)
+        mutator = the_space.constant_mutator_for("Foo")
+
+        in_new_space_scope do
+          subspace = RSpec::Mocks.space
+          expect(subspace.constant_mutator_for("Foo")).to equal(mutator)
+        end
+      end
+    end
+
+    describe "#any_instance_recorder_for" do
+      it 'returns the recorder for the given class' do
+        expect(space.any_instance_recorder_for(String)).to equal(space.any_instance_recorder_for(String))
+        expect(space.any_instance_recorder_for(Symbol)).to equal(space.any_instance_recorder_for(Symbol))
+        expect(space.any_instance_recorder_for(String)).not_to equal(space.any_instance_recorder_for(Symbol))
+      end
+
+      it 'can stil return a recorder from a parent context' do
+        recorder = space.any_instance_recorder_for(String)
+        subspace = space.new_scope
+
+        expect(subspace.any_instance_recorder_for(String)).to equal(recorder)
+      end
+
+      it "does not store a parent's proxy in the child space" do
+        space.any_instance_recorder_for(String)
+        subspace = space.new_scope
+
+        expect {
+          subspace.any_instance_recorder_for(String)
+        }.not_to change { subspace.any_instance_recorders }.from({})
+      end
+    end
+
+    it 'can be diffed in a failure when it has references to an error generator via a proxy' do
+      space1 = Space.new
+      space2 = Space.new
+
+      space1.proxy_for("")
+      space2.proxy_for("")
+
+      expect {
+        expect(space1).to eq(space2)
+      }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /Diff/)
+    end
+
+    def in_new_space_scope
+      RSpec::Mocks.setup
+      yield
+    ensure
+      RSpec::Mocks.teardown
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/spy_spec.rb b/rspec-mocks/spec/rspec/mocks/spy_spec.rb
new file mode 100644
index 0000000..57868a2
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/spy_spec.rb
@@ -0,0 +1,127 @@
+require "spec_helper"
+
+RSpec.describe "the spy family of methods" do
+  describe "spy" do
+    it "responds to arbitrary methods" do
+      expect(spy.respond_to?(:foo)).to be true
+    end
+
+    it "takes a name" do
+      expect(spy(:bacon_bits).inspect).to include("bacon_bits")
+    end
+
+    it "records called methods" do
+      expect(spy.tap { |s| s.foo }).to have_received(:foo)
+    end
+
+    it "takes a hash of method names and return values" do
+      expect(spy(:foo => :bar).foo).to eq(:bar)
+    end
+
+    it "takes a name and a hash of method names and return values" do
+      expect(spy(:bacon_bits, :foo => :bar).foo).to eq(:bar)
+    end
+  end
+
+  shared_examples_for "a verifying spy with a foo method" do
+    it "responds to methods on the verified object" do
+      expect(subject.respond_to?(:foo)).to be true
+    end
+
+    it "does not respond to methods that are not on the verified object" do
+      expect(subject.respond_to?(:other_method)).to be false
+    end
+
+    it "records called methods" do
+      expect(subject.tap { |s| s.foo}).to have_received(:foo)
+    end
+
+    it 'fails fast when `have_received` is passed an undefined method name' do
+      expect {
+        expect(subject).to have_received(:bar)
+      }.to fail_matching("does not implement")
+    end
+
+    it 'fails fast when negative `have_received` is passed an undefined method name' do
+      expect {
+        expect(subject).to_not have_received(:bar)
+      }.to fail_matching("does not implement")
+    end
+  end
+
+  describe "instance_spy" do
+    context "when passing a class object" do
+      let(:the_class) do
+        Class.new do
+          def foo
+            3
+          end
+        end
+      end
+
+      subject { instance_spy(the_class) }
+
+      it_behaves_like "a verifying spy with a foo method"
+
+      it "takes a class and a hash of method names and return values" do
+        expect(instance_spy(the_class, :foo => :bar).foo).to eq(:bar)
+      end
+    end
+
+    context "passing a class by string reference" do
+      DummyClass = Class.new do
+        def foo
+          3
+        end
+      end
+
+      let(:the_class) { "DummyClass" }
+
+      subject { instance_spy(the_class) }
+
+      it_behaves_like "a verifying spy with a foo method"
+
+      it "takes a class name string and a hash of method names and return values" do
+        expect(instance_spy(the_class, :foo => :bar).foo).to eq(:bar)
+      end
+    end
+  end
+
+  describe "object_spy" do
+    let(:the_class) do
+      Class.new do
+        def foo
+          3
+        end
+      end
+    end
+
+    let(:the_instance) { the_class.new }
+
+    subject { object_spy(the_instance) }
+
+    it_behaves_like "a verifying spy with a foo method"
+
+    it "takes an instance and a hash of method names and return values" do
+      expect(object_spy(the_instance, :foo => :bar).foo).to eq(:bar)
+    end
+  end
+
+  describe "class_spy" do
+    let(:the_class) do
+      Class.new do
+        def self.foo
+          3
+        end
+      end
+    end
+
+    subject { class_spy(the_class) }
+
+    it_behaves_like "a verifying spy with a foo method"
+
+    it "takes a class and a hash of method names and return values" do
+      expect(class_spy(the_class, :foo => :bar).foo).to eq(:bar)
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/standalone_spec.rb b/rspec-mocks/spec/rspec/mocks/standalone_spec.rb
new file mode 100644
index 0000000..bb5822c
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/standalone_spec.rb
@@ -0,0 +1,27 @@
+require 'rspec/support/spec/in_sub_process'
+main = self
+
+RSpec.describe "Loading rspec/mocks/standalone" do
+  include RSpec::Support::InSubProcess
+
+  it "exposes the RSpec::Mocks API on `main`" do
+    in_sub_process do
+      require 'rspec/mocks/standalone'
+      main.instance_eval do
+        dbl = double
+        expect(dbl).to receive(:foo)
+        dbl.foo
+        RSpec::Mocks.verify
+        RSpec::Mocks.teardown
+      end
+    end
+  end
+
+  it "does not infect other objects with the RSpec::Mocks API" do
+    in_sub_process do
+      require 'rspec/mocks/standalone'
+      object = Object.new
+      expect(object).not_to respond_to(:double, :expect)
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/stash_spec.rb b/rspec-mocks/spec/rspec/mocks/stash_spec.rb
new file mode 100644
index 0000000..93a2029
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/stash_spec.rb
@@ -0,0 +1,43 @@
+module RSpec
+  module Mocks
+    RSpec.describe "only stashing the original method" do
+      let(:klass) do
+        Class.new do
+          def self.foo(arg)
+            :original_value
+          end
+        end
+      end
+
+      it "keeps the original method intact after multiple expectations are added on the same method" do
+        expect(klass).to receive(:foo).with(:fizbaz).and_return(:wowwow)
+        expect(klass).to receive(:foo).with(:bazbar).and_return(:okay)
+
+        klass.foo(:fizbaz)
+        klass.foo(:bazbar)
+        verify klass
+
+        reset klass
+        expect(klass.foo(:yeah)).to equal(:original_value)
+      end
+    end
+
+    RSpec.describe "when a class method is aliased on a subclass and the method is mocked" do
+      it "restores the original aliased public method" do
+        klass = Class.new do
+          class << self
+            alias alternate_new new
+          end
+        end
+
+        expect(klass).to receive(:alternate_new)
+        expect(klass.alternate_new).to be_nil
+
+        verify klass
+
+        reset klass
+        expect(klass.alternate_new).to be_an_instance_of(klass)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/stub_chain_spec.rb b/rspec-mocks/spec/rspec/mocks/stub_chain_spec.rb
new file mode 100644
index 0000000..1db7d27
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/stub_chain_spec.rb
@@ -0,0 +1,166 @@
+module RSpec
+  module Mocks
+    RSpec.describe "A chained method stub" do
+      let(:object) { Object.new }
+
+      it 'does not get confused by symbol vs string usage for the messages' do
+        allow(object).to receive_message_chain(:foo, :bar => 1)
+        allow(object).to receive_message_chain("foo", :bazz => 2)
+
+        expect(object.foo.bar).to eq(1)
+        expect(object.foo.bazz).to eq(2)
+      end
+
+      context "with one method in chain" do
+        context "using and_return" do
+          it "returns expected value from chaining only one method call" do
+            allow(object).to receive_message_chain(:msg1).and_return(:return_value)
+            expect(object.msg1).to equal(:return_value)
+          end
+        end
+
+        context "using a block" do
+          it "returns the correct value" do
+            allow(object).to receive_message_chain(:msg1) { :return_value }
+            expect(object.msg1).to equal(:return_value)
+          end
+        end
+
+        context "using a hash" do
+          it "returns the value of the key/value pair" do
+            allow(object).to receive_message_chain(:msg1 => :return_value)
+            expect(object.msg1).to equal(:return_value)
+          end
+        end
+      end
+
+      context "with two methods in chain" do
+        it "accepts any number of arguments to the stubbed messages in the chain" do
+          allow(object).to receive_message_chain(:msg1, :msg2).and_return(:return_value)
+
+          expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
+        end
+
+        context "using and_return" do
+          it "returns expected value from chaining two method calls" do
+            allow(object).to receive_message_chain(:msg1, :msg2).and_return(:return_value)
+            expect(object.msg1.msg2).to equal(:return_value)
+          end
+        end
+
+        context "using a block" do
+          it "returns the correct value" do
+            allow(object).to receive_message_chain(:msg1, :msg2) { :return_value }
+            expect(object.msg1.msg2).to equal(:return_value)
+          end
+        end
+
+        context "using a hash" do
+          it "returns the value of the key/value pair" do
+            allow(object).to receive_message_chain(:msg1, :msg2 => :return_value)
+            expect(object.msg1.msg2).to equal(:return_value)
+          end
+        end
+      end
+
+      context "with four methods in chain" do
+        context "using and_return" do
+          it "returns expected value from chaining two method calls" do
+            allow(object).to receive_message_chain(:msg1, :msg2, :msg3, :msg4).and_return(:return_value)
+            expect(object.msg1.msg2.msg3.msg4).to equal(:return_value)
+          end
+        end
+
+        context "using a block" do
+          it "returns the correct value" do
+            allow(object).to receive_message_chain(:msg1, :msg2, :msg3, :msg4) { :return_value }
+            expect(object.msg1.msg2.msg3.msg4).to equal(:return_value)
+          end
+        end
+
+        context "using a hash" do
+          it "returns the value of the key/value pair" do
+            allow(object).to receive_message_chain(:msg1, :msg2, :msg3, :msg4 => :return_value)
+            expect(object.msg1.msg2.msg3.msg4).to equal(:return_value)
+          end
+        end
+
+        context "using a hash with a string key" do
+          it "returns the value of the key/value pair" do
+            allow(object).to receive_message_chain("msg1.msg2.msg3.msg4" => :return_value)
+            expect(object.msg1.msg2.msg3.msg4).to equal(:return_value)
+          end
+        end
+      end
+
+      it "returns expected value from chaining four method calls" do
+        allow(object).to receive_message_chain(:msg1, :msg2, :msg3, :msg4).and_return(:return_value)
+        expect(object.msg1.msg2.msg3.msg4).to equal(:return_value)
+      end
+
+      context "with messages shared across multiple chains" do
+        context "using and_return" do
+          context "starting with the same message" do
+            it "returns expected value" do
+              allow(object).to receive_message_chain(:msg1, :msg2, :msg3).and_return(:first)
+              allow(object).to receive_message_chain(:msg1, :msg2, :msg4).and_return(:second)
+
+              expect(object.msg1.msg2.msg3).to equal(:first)
+              expect(object.msg1.msg2.msg4).to equal(:second)
+            end
+          end
+
+          context "starting with the different messages" do
+            it "returns expected value" do
+              allow(object).to receive_message_chain(:msg1, :msg2, :msg3).and_return(:first)
+              allow(object).to receive_message_chain(:msg4, :msg2, :msg3).and_return(:second)
+
+              expect(object.msg1.msg2.msg3).to equal(:first)
+              expect(object.msg4.msg2.msg3).to equal(:second)
+            end
+          end
+        end
+
+        context "using => value" do
+          context "starting with the same message" do
+            it "returns expected value" do
+              allow(object).to receive_message_chain(:msg1, :msg2, :msg3 => :first)
+              allow(object).to receive_message_chain(:msg1, :msg2, :msg4 => :second)
+
+              expect(object.msg1.msg2.msg3).to equal(:first)
+              expect(object.msg1.msg2.msg4).to equal(:second)
+            end
+          end
+
+          context "starting with different messages" do
+            it "returns expected value" do
+              allow(object).to receive_message_chain(:msg1, :msg2, :msg3 => :first)
+              allow(object).to receive_message_chain(:msg4, :msg2, :msg3 => :second)
+
+              expect(object.msg1.msg2.msg3).to equal(:first)
+              expect(object.msg4.msg2.msg3).to equal(:second)
+            end
+          end
+        end
+      end
+
+      it "returns expected value when chain is a dot separated string, like stub_chain('msg1.msg2.msg3')" do
+        allow(object).to receive_message_chain("msg1.msg2.msg3").and_return(:return_value)
+        expect(object.msg1.msg2.msg3).to equal(:return_value)
+      end
+
+      it "returns expected value from two chains with shared messages at the beginning" do
+        allow(object).to receive_message_chain(:msg1, :msg2, :msg3, :msg4).and_return(:first)
+        allow(object).to receive_message_chain(:msg1, :msg2, :msg3, :msg5).and_return(:second)
+
+        expect(object.msg1.msg2.msg3.msg4).to equal(:first)
+        expect(object.msg1.msg2.msg3.msg5).to equal(:second)
+      end
+
+      it "handles private instance methods (like Object#select) in the middle of a chain" do
+        allow(object).to receive_message_chain(:msg1, :select, :msg3 => 'answer')
+        expect(object.msg1.select.msg3).to eq 'answer'
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/stub_implementation_spec.rb b/rspec-mocks/spec/rspec/mocks/stub_implementation_spec.rb
new file mode 100644
index 0000000..9507f38
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/stub_implementation_spec.rb
@@ -0,0 +1,98 @@
+module RSpec
+  module Mocks
+    RSpec.describe "stub implementation" do
+      describe "with no args" do
+        it "execs the block when called" do
+          obj = double()
+          allow(obj).to receive(:foo) { :bar }
+          expect(obj.foo).to eq :bar
+        end
+      end
+
+      describe "with one arg" do
+        it "execs the block with that arg when called" do
+          obj = double()
+          allow(obj).to receive(:foo) {|given| given}
+          expect(obj.foo(:bar)).to eq :bar
+        end
+      end
+
+      describe "with variable args" do
+        it "execs the block when called" do
+          obj = double()
+          allow(obj).to receive(:foo) {|*given| given.first}
+          expect(obj.foo(:bar)).to eq :bar
+        end
+      end
+    end
+
+    RSpec.describe "unstubbing with `and_call_original`" do
+      it "replaces the stubbed method with the original method" do
+        obj = Object.new
+        def obj.foo; :original; end
+        allow(obj).to receive(:foo)
+        allow(obj).to receive(:foo).and_call_original
+        expect(obj.foo).to eq :original
+      end
+
+      it "removes all stubs with the supplied method name" do
+        obj = Object.new
+        def obj.foo; :original; end
+        allow(obj).to receive(:foo).with(1)
+        allow(obj).to receive(:foo).with(2)
+        allow(obj).to receive(:foo).and_call_original
+        expect(obj.foo).to eq :original
+      end
+
+      it "does not remove any expectations with the same method name" do
+        obj = Object.new
+        def obj.foo; :original; end
+        expect(obj).to receive(:foo).with(3).and_return(:three)
+        allow(obj).to receive(:foo).with(1)
+        allow(obj).to receive(:foo).with(2)
+        allow(obj).to receive(:foo).and_call_original
+        expect(obj.foo(3)).to eq :three
+      end
+
+      shared_examples_for "stubbing `new` on class objects" do
+        it "restores the correct implementations when stubbed and unstubbed on a parent and child class" do
+          parent = stub_const("Parent", Class.new)
+          child  = stub_const("Child", Class.new(parent))
+
+          allow(parent).to receive(:new)
+          allow(child).to receive(:new)
+          allow(parent).to receive(:new).and_call_original
+          allow(child).to receive(:new).and_call_original
+
+          expect(parent.new).to be_an_instance_of parent
+          expect(child.new).to be_an_instance_of child
+        end
+
+        it "restores the correct implementations when stubbed and unstubbed on a grandparent and grandchild class" do
+          grandparent = stub_const("GrandParent", Class.new)
+          parent      = stub_const("Parent", Class.new(grandparent))
+          child       = stub_const("Child", Class.new(parent))
+
+          allow(grandparent).to receive(:new)
+          allow(child).to receive(:new)
+          allow(grandparent).to receive(:new).and_call_original
+          allow(child).to receive(:new).and_call_original
+
+          expect(grandparent.new).to be_an_instance_of grandparent
+          expect(child.new).to be_an_instance_of child
+        end
+      end
+
+      context "when partial doubles are not verified" do
+        before { expect(RSpec::Mocks.configuration.verify_partial_doubles?).to be false }
+        include_examples "stubbing `new` on class objects"
+      end
+
+      context "when partial doubles are verified" do
+        include_context "with isolated configuration"
+        before { RSpec::Mocks.configuration.verify_partial_doubles = true }
+        include_examples "stubbing `new` on class objects"
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/stub_spec.rb b/rspec-mocks/spec/rspec/mocks/stub_spec.rb
new file mode 100644
index 0000000..d210a95
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/stub_spec.rb
@@ -0,0 +1,540 @@
+module RSpec
+  module Mocks
+    RSpec.describe "A method stub" do
+      before(:each) do
+        @class = Class.new do
+          class << self
+            def existing_class_method
+              existing_private_class_method
+            end
+
+            private
+            def existing_private_class_method
+              :original_value
+            end
+          end
+
+          def existing_instance_method
+            existing_private_instance_method
+          end
+
+          private
+          def existing_private_instance_method
+            :original_value
+          end
+        end
+        @instance = @class.new
+        @stub = Object.new
+      end
+
+      describe "using `and_return`" do
+        it "returns declared value when message is received" do
+          allow(@instance).to receive(:msg).and_return(:return_value)
+          expect(@instance.msg).to equal(:return_value)
+          verify @instance
+        end
+      end
+
+      it "instructs an instance to respond_to the message" do
+        allow(@instance).to receive(:msg)
+        expect(@instance).to respond_to(:msg)
+      end
+
+      it "instructs a class object to respond_to the message" do
+        allow(@class).to receive(:msg)
+        expect(@class).to respond_to(:msg)
+      end
+
+      it "ignores when expected message is received with no args" do
+        allow(@instance).to receive(:msg)
+        @instance.msg
+        expect do
+          verify @instance
+        end.not_to raise_error
+      end
+
+      it "ignores when message is received with args" do
+        allow(@instance).to receive(:msg)
+        @instance.msg(:an_arg)
+        expect do
+          verify @instance
+        end.not_to raise_error
+      end
+
+      it "ignores when expected message is not received" do
+        allow(@instance).to receive(:msg)
+        expect do
+          verify @instance
+        end.not_to raise_error
+      end
+
+      it "handles multiple stubbed methods" do
+        allow(@instance).to receive_messages(:msg1 => 1, :msg2 => 2)
+        expect(@instance.msg1).to eq(1)
+        expect(@instance.msg2).to eq(2)
+      end
+
+      it "is retained when stubbed object is `clone`d" do
+        allow(@stub).to receive(:foobar).and_return(1)
+        expect(@stub.clone.foobar).to eq(1)
+      end
+
+      it "is cleared when stubbed object when `dup`ed" do
+        allow(@stub).to receive(:foobar).and_return(1)
+        expect{ @stub.dup.foobar }.to raise_error NoMethodError, /foobar/
+      end
+
+      context "using `with`" do
+        it 'determines which value is returned' do
+          allow(@stub).to receive(:foo).with(1) { :one }
+          allow(@stub).to receive(:foo).with(2) { :two }
+
+          expect(@stub.foo(2)).to eq(:two)
+          expect(@stub.foo(1)).to eq(:one)
+        end
+
+        it 'allows differing arities' do
+          allow(@stub).to receive(:foo).with(:two, :args) { :two_args }
+          allow(@stub).to receive(:foo).with(:three, :args, :total) { :three_args_total }
+
+          expect(@stub.foo(:two, :args)).to eq(:two_args)
+          expect(@stub.foo(:three, :args, :total)).to eq(:three_args_total)
+        end
+      end
+
+      context "when the stubbed method is called" do
+        it "does not call any methods on the passed args, since that could mutate them", :issue => 892 do
+          recorder = Class.new(defined?(::BasicObject) ? ::BasicObject : ::Object) do
+            def called_methods
+              @called_methods ||= []
+            end
+
+            def method_missing(name, *)
+              called_methods << name
+              self
+            end
+          end.new
+
+          allow(@stub).to receive(:foo)
+          expect {
+            @stub.foo(recorder)
+          }.not_to change(recorder, :called_methods)
+        end
+      end
+
+      context "stubbing with prepend", :if => Support::RubyFeatures.module_prepends_supported? do
+        module ToBePrepended
+          def value
+            "#{super}_prepended".to_sym
+          end
+        end
+
+        it "handles stubbing prepended methods" do
+          klass = Class.new { prepend ToBePrepended; def value; :original; end }
+          instance = klass.new
+          expect(instance.value).to eq :original_prepended
+          allow(instance).to receive(:value) { :stubbed }
+          expect(instance.value).to eq :stubbed
+        end
+
+        it "handles stubbing prepended methods on a class's singleton class" do
+          klass = Class.new { class << self; prepend ToBePrepended; end; def self.value; :original; end }
+          expect(klass.value).to eq :original_prepended
+          allow(klass).to receive(:value) { :stubbed }
+          expect(klass.value).to eq :stubbed
+        end
+
+        it "handles stubbing prepended methods on an object's singleton class" do
+          object = Object.new
+          def object.value; :original; end
+          object.singleton_class.send(:prepend, ToBePrepended)
+
+          expect(object.value).to eq :original_prepended
+          allow(object).to receive(:value) { :stubbed }
+          expect(object.value).to eq :stubbed
+        end
+
+        it 'does not unnecessarily prepend a module when the prepended module does not override the stubbed method' do
+          object = Object.new
+          def object.value; :original; end
+          object.singleton_class.send(:prepend, Module.new)
+
+          expect {
+            allow(object).to receive(:value) { :stubbed }
+          }.not_to change { object.singleton_class.ancestors }
+        end
+
+        it 'does not unnecessarily prepend a module when stubbing a method on a module extended onto itself' do
+          mod = Module.new do
+            extend self
+            def foo; :bar; end
+          end
+
+          expect {
+            allow(mod).to receive(:foo)
+          }.not_to change { mod.singleton_class.ancestors }
+        end
+
+        it 'does not unnecessarily prepend a module when the module was included' do
+          object = Object.new
+          def object.value; :original; end
+          object.singleton_class.send(:include, ToBePrepended)
+
+          expect {
+            allow(object).to receive(:value) { :stubbed }
+          }.not_to change { object.singleton_class.ancestors }
+        end
+
+        it 'reuses our prepend module so as not to keep mutating the ancestors' do
+          object = Object.new
+          def object.value; :original; end
+          object.singleton_class.send(:prepend, ToBePrepended)
+          allow(object).to receive(:value) { :stubbed }
+
+          RSpec::Mocks.teardown
+          RSpec::Mocks.setup
+
+          expect {
+            allow(object).to receive(:value) { :stubbed }
+          }.not_to change { object.singleton_class.ancestors }
+        end
+
+        context "when multiple modules are prepended, only one of which overrides the stubbed method" do
+          it "can still be stubbed and reset" do
+            object = Object.new
+            object.singleton_class.class_eval do
+              def value; :original; end
+              prepend ToBePrepended
+              prepend Module.new { }
+            end
+
+            expect(object.value).to eq :original_prepended
+            allow(object).to receive(:value) { :stubbed }
+            expect(object.value).to eq :stubbed
+            reset object
+            expect(object.value).to eq :original_prepended
+          end
+        end
+
+        context "when a module with a method override is prepended after reset" do
+          it "can still be stubbed again" do
+            object = Object.new
+            def object.value; :original; end
+            object.singleton_class.send(:prepend, ToBePrepended)
+            allow(object).to receive(:value) { :stubbed }
+
+            RSpec::Mocks.teardown
+            RSpec::Mocks.setup
+
+            object.singleton_class.send(:prepend, Module.new {
+              def value
+                :"#{super}_extra_prepend"
+              end
+            })
+
+            allow(object).to receive(:value) { :stubbed_2 }
+            expect(object.value).to eq(:stubbed_2)
+          end
+        end
+      end
+
+      describe "#rspec_reset" do
+        it "removes stubbed methods that didn't exist" do
+          allow(@instance).to receive(:non_existent_method)
+          reset @instance
+          expect(@instance).not_to respond_to(:non_existent_method)
+        end
+
+        it "restores existing instance methods" do
+          # See bug reports 8302 and 7805
+          allow(@instance).to receive(:existing_instance_method) { :stub_value }
+          reset @instance
+          expect(@instance.existing_instance_method).to eq(:original_value)
+        end
+
+        it "restores existing singleton methods with the appropriate context" do
+          klass = Class.new do
+            def self.say_hello
+              @hello if defined?(@hello)
+            end
+          end
+
+          subclass = Class.new(klass)
+
+          subclass.instance_variable_set(:@hello, "Hello")
+          expect(subclass.say_hello).to eq("Hello")
+
+          allow(klass).to receive(:say_hello) { "Howdy" }
+          expect(subclass.say_hello).to eq("Howdy")
+
+          reset klass
+          expect(subclass.say_hello).to eq("Hello")
+        end
+
+        it "restores existing private instance methods" do
+          # See bug reports 8302 and 7805
+          allow(@instance).to receive(:existing_private_instance_method) { :stub_value }
+          reset @instance
+          expect(@instance.send(:existing_private_instance_method)).to eq(:original_value)
+        end
+
+        it "restores existing class methods" do
+          # See bug reports 8302 and 7805
+          allow(@class).to receive(:existing_class_method) { :stub_value }
+          reset @class
+          expect(@class.existing_class_method).to eq(:original_value)
+        end
+
+        it "restores existing private class methods" do
+          # See bug reports 8302 and 7805
+          allow(@class).to receive(:existing_private_class_method) { :stub_value }
+          reset @class
+          expect(@class.send(:existing_private_class_method)).to eq(:original_value)
+        end
+
+        it "does not remove existing methods that have been stubbed twice" do
+          allow(@instance).to receive(:existing_instance_method)
+          allow(@instance).to receive(:existing_instance_method)
+
+          reset @instance
+
+          expect(@instance.existing_instance_method).to eq(:original_value)
+        end
+
+        it "correctly restores the visibility of methods whose visibility has been tweaked on the singleton class" do
+          # hello is a private method when mixed in, but public on the module
+          # itself
+          mod = Module.new {
+            extend self
+            def hello; :hello; end
+
+            private :hello
+            class << self; public :hello; end;
+          }
+
+          expect(mod.hello).to eq(:hello)
+
+          allow(mod).to receive(:hello) { :stub }
+          reset mod
+
+          expect(mod.hello).to eq(:hello)
+        end
+
+        it "correctly handles stubbing inherited mixed in class methods" do
+          mod = Module.new do
+                  def method_a
+                    raise "should not execute method_a"
+                  end
+
+                  def self.included(other)
+                    other.extend self
+                  end
+                end
+
+          a = Class.new { include mod }
+          b = Class.new(a) do
+                def self.method_b
+                  "executed method_b"
+                end
+              end
+
+          allow(a).to receive(:method_a)
+          allow(b).to receive(:method_b).and_return("stubbed method_b")
+
+          expect(b.method_b).to eql("stubbed method_b")
+        end
+
+        if Support::RubyFeatures.module_prepends_supported?
+          context "with a prepended module (ruby 2.0.0+)" do
+            module ToBePrepended
+              def existing_method
+                "#{super}_prepended".to_sym
+              end
+            end
+
+            before do
+              @prepended_class = Class.new do
+                prepend ToBePrepended
+
+                def existing_method
+                  :original_value
+                end
+
+                def non_prepended_method
+                  :not_prepended
+                end
+              end
+              @prepended_instance = @prepended_class.new
+            end
+
+            it "restores prepended instance methods" do
+              allow(@prepended_instance).to receive(:existing_method) { :stubbed }
+              expect(@prepended_instance.existing_method).to eq :stubbed
+
+              reset @prepended_instance
+              expect(@prepended_instance.existing_method).to eq :original_value_prepended
+            end
+
+            it "restores non-prepended instance methods" do
+              allow(@prepended_instance).to receive(:non_prepended_method) { :stubbed }
+              expect(@prepended_instance.non_prepended_method).to eq :stubbed
+
+              reset @prepended_instance
+              expect(@prepended_instance.non_prepended_method).to eq :not_prepended
+            end
+
+            it "restores prepended class methods" do
+              klass = Class.new do
+                class << self; prepend ToBePrepended; end
+                def self.existing_method
+                  :original_value
+                end
+              end
+
+              allow(klass).to receive(:existing_method) { :stubbed }
+              expect(klass.existing_method).to eq :stubbed
+
+              reset klass
+              expect(klass.existing_method).to eq :original_value_prepended
+            end
+
+            it "restores prepended object singleton methods" do
+              object = Object.new
+              def object.existing_method; :original_value; end
+              object.singleton_class.send(:prepend, ToBePrepended)
+
+              allow(object).to receive(:existing_method) { :stubbed }
+              expect(object.existing_method).to eq :stubbed
+
+              reset object
+              expect(object.existing_method).to eq :original_value_prepended
+            end
+          end
+        end
+      end
+
+      it "returns values in order to consecutive calls" do
+        allow(@instance).to receive(:msg).and_return("1",2,:three)
+        expect(@instance.msg).to eq("1")
+        expect(@instance.msg).to eq(2)
+        expect(@instance.msg).to eq(:three)
+      end
+
+      it "keeps returning last value in consecutive calls" do
+        allow(@instance).to receive(:msg).and_return("1",2,:three)
+        expect(@instance.msg).to eq("1")
+        expect(@instance.msg).to eq(2)
+        expect(@instance.msg).to eq(:three)
+        expect(@instance.msg).to eq(:three)
+        expect(@instance.msg).to eq(:three)
+      end
+
+      it "yields a specified object" do
+        allow(@instance).to receive(:method_that_yields).and_yield(:yielded_obj)
+        current_value = :value_before
+        @instance.method_that_yields {|val| current_value = val}
+        expect(current_value).to eq :yielded_obj
+        verify @instance
+      end
+
+      it "yields multiple times with multiple calls to and_yield" do
+        allow(@instance).to receive(:method_that_yields_multiple_times).and_yield(:yielded_value).
+                                                       and_yield(:another_value)
+        current_value = []
+        @instance.method_that_yields_multiple_times {|val| current_value << val}
+        expect(current_value).to eq [:yielded_value, :another_value]
+        verify @instance
+      end
+
+      it "yields a specified object and return another specified object" do
+        yielded_obj = double("my mock")
+        expect(yielded_obj).to receive(:foo).with(:bar)
+        allow(@instance).to receive(:method_that_yields_and_returns).and_yield(yielded_obj).and_return(:baz)
+        expect(@instance.method_that_yields_and_returns { |o| o.foo :bar }).to eq :baz
+      end
+
+      it "throws when told to" do
+        allow(@stub).to receive(:something).and_throw(:up)
+        expect { @stub.something }.to throw_symbol(:up)
+      end
+
+      it "throws with argument when told to" do
+        allow(@stub).to receive(:something).and_throw(:up, 'high')
+        expect { @stub.something }.to throw_symbol(:up, 'high')
+      end
+
+      it "overrides a pre-existing method" do
+        allow(@stub).to receive(:existing_instance_method).and_return(:updated_stub_value)
+        expect(@stub.existing_instance_method).to eq :updated_stub_value
+      end
+
+      it "overrides a pre-existing stub" do
+        allow(@stub).to receive(:foo) { 'bar' }
+        allow(@stub).to receive(:foo) { 'baz' }
+        expect(@stub.foo).to eq 'baz'
+      end
+
+      it "allows a stub and an expectation" do
+        allow(@stub).to receive(:foo).with("bar")
+        expect(@stub).to receive(:foo).with("baz")
+        @stub.foo("bar")
+        @stub.foo("baz")
+      end
+    end
+
+    RSpec.describe "A method stub with args" do
+      before(:each) do
+        @stub = Object.new
+        allow(@stub).to receive(:foo).with("bar")
+      end
+
+      it "does not complain if not called" do
+      end
+
+      it "does not complain if called with arg" do
+        @stub.foo("bar")
+      end
+
+      it "complains if called with no arg" do
+        expect {
+          @stub.foo
+        }.to raise_error(/received :foo with unexpected arguments/)
+      end
+
+      it "complains if called with other arg", :github_issue => [123,147] do
+        expect {
+          @stub.foo("other")
+        }.to raise_error(/received :foo with unexpected arguments.*Please stub a default value/m)
+      end
+
+      it "does not complain if also mocked w/ different args" do
+        expect(@stub).to receive(:foo).with("baz")
+        @stub.foo("bar")
+        @stub.foo("baz")
+      end
+
+      it "complains if also mocked w/ different args AND called w/ a 3rd set of args" do
+        expect(@stub).to receive(:foo).with("baz")
+        @stub.foo("bar")
+        @stub.foo("baz")
+        expect {
+          @stub.foo("other")
+        }.to raise_error
+      end
+
+      it 'uses the correct stubbed response when responding to a mock expectation' do
+        allow(@stub).to receive(:bar) { 15 }
+        allow(@stub).to receive(:bar).with(:eighteen) { 18 }
+        allow(@stub).to receive(:bar).with(:thirteen) { 13 }
+
+        expect(@stub).to receive(:bar).exactly(4).times
+
+        expect(@stub.bar(:blah)).to eq(15)
+        expect(@stub.bar(:thirteen)).to eq(13)
+        expect(@stub.bar(:eighteen)).to eq(18)
+        expect(@stub.bar).to eq(15)
+      end
+    end
+
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/stubbed_message_expectations_spec.rb b/rspec-mocks/spec/rspec/mocks/stubbed_message_expectations_spec.rb
new file mode 100644
index 0000000..22222bc
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/stubbed_message_expectations_spec.rb
@@ -0,0 +1,56 @@
+RSpec.describe "expection set on previously stubbed method" do
+  it "fails if message is not received after expectation is set" do
+    dbl = double(:msg => nil)
+    dbl.msg
+    expect(dbl).to receive(:msg)
+    expect { verify dbl }.to raise_error(RSpec::Mocks::MockExpectationError)
+  end
+
+  it "outputs arguments of similar calls" do
+    dbl = double('double', :foo => true)
+    expect(dbl).to receive(:foo).with('first')
+    dbl.foo('second')
+    dbl.foo('third')
+    expect {
+      verify dbl
+    }.to raise_error(%Q|Double "double" received :foo with unexpected arguments\n  expected: ("first")\n       got: ("second"), ("third")|)
+    reset dbl
+  end
+
+  context "with argument constraint on stub" do
+    it "matches any args if no arg constraint set on expectation" do
+      dbl = double("mock")
+      allow(dbl).to receive(:foo).with(3).and_return("stub")
+      expect(dbl).to receive(:foo).at_least(:once).and_return("expectation")
+      dbl.foo
+      verify dbl
+    end
+
+    it "matches specific args set on expectation" do
+      dbl = double("mock")
+      allow(dbl).to receive(:foo).with(3).and_return("stub")
+      expect(dbl).to receive(:foo).at_least(:once).with(4).and_return("expectation")
+      dbl.foo(4)
+      verify dbl
+    end
+
+    it "fails if expectation's arg constraint is not met" do
+      dbl = double("mock")
+      allow(dbl).to receive(:foo).with(3).and_return("stub")
+      expect(dbl).to receive(:foo).at_least(:once).with(4).and_return("expectation")
+      dbl.foo(3)
+      expect { verify dbl }.to raise_error(/expected: \(4\)\s+got: \(3\)/)
+    end
+
+    it 'distinguishes between individual values and arrays properly' do
+      dbl = double
+      allow(dbl).to receive(:foo).with('a', ['b'])
+
+      expect {
+        dbl.foo(['a'], 'b')
+      }.to raise_error { |e|
+        expect(e.message).to include('expected: ("a", ["b"])', 'got: (["a"], "b")')
+      }
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb b/rspec-mocks/spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb
new file mode 100644
index 0000000..678650e
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/syntax_agnostic_message_matchers_spec.rb
@@ -0,0 +1,99 @@
+module RSpec
+  module Mocks
+
+    RSpec.describe ".allow_message" do
+      let(:subject) { Object.new }
+
+      it "sets up basic message allowance" do
+        expect {
+          ::RSpec::Mocks.allow_message(subject, :basic)
+        }.to change {
+          subject.respond_to?(:basic)
+        }.to(true)
+
+        expect(subject.basic).to eq(nil)
+      end
+
+      it "sets up message allowance with params and return value" do
+        expect {
+          ::RSpec::Mocks.allow_message(subject, :x).with(:in).and_return(:out)
+        }.to change {
+          subject.respond_to?(:x)
+        }.to(true)
+
+        expect(subject.x(:in)).to eq(:out)
+      end
+
+      it "supports block implementations" do
+        ::RSpec::Mocks.allow_message(subject, :message) { :value }
+        expect(subject.message).to eq(:value)
+      end
+
+      it "does not set an expectation that the message will be received" do
+        ::RSpec::Mocks.allow_message(subject, :message)
+        expect { verify subject }.not_to raise_error
+      end
+
+      it 'does not get confused when the string and symbol message form are both used' do
+        ::RSpec::Mocks.allow_message(subject, :foo).with(1) { :a }
+        ::RSpec::Mocks.allow_message(subject, "foo").with(2) { :b }
+
+        expect(subject.foo(1)).to eq(:a)
+        expect(subject.foo(2)).to eq(:b)
+
+        reset subject
+      end
+    end
+
+    RSpec.describe ".expect_message" do
+      let(:subject) { Object.new }
+
+      it "sets up basic message expectation, verifies as uncalled" do
+        expect {
+          ::RSpec::Mocks.expect_message(subject, :basic)
+        }.to change {
+          subject.respond_to?(:basic)
+        }.to(true)
+
+        expect { verify subject }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails if never is specified and the message is called" do
+        expect {
+          ::RSpec::Mocks.expect_message(subject, :foo).never
+          subject.foo
+        }.to raise_error(/expected.*0 times/)
+      end
+
+      it "sets up basic message expectation, verifies as called" do
+        ::RSpec::Mocks.expect_message(subject, :basic)
+        subject.basic
+        verify subject
+      end
+
+      it "sets up message expectation with params and return value" do
+        ::RSpec::Mocks.expect_message(subject, :msg).with(:in).and_return(:out)
+        expect(subject.msg(:in)).to eq(:out)
+        verify subject
+      end
+
+      it "accepts a block implementation for the expected message" do
+        ::RSpec::Mocks.expect_message(subject, :msg) { :value }
+        expect(subject.msg).to eq(:value)
+        verify subject
+      end
+
+      it 'does not get confused when the string and symbol message form are both used' do
+        ::RSpec::Mocks.expect_message(subject, :foo).with(1)
+        ::RSpec::Mocks.expect_message(subject, "foo").with(2)
+
+        subject.foo(1)
+        subject.foo(2)
+
+        verify subject
+      end
+
+    end
+
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/syntax_spec.rb b/rspec-mocks/spec/rspec/mocks/syntax_spec.rb
new file mode 100644
index 0000000..ad84af8
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/syntax_spec.rb
@@ -0,0 +1,7 @@
+module RSpec
+  RSpec.describe Mocks do
+    it "does not inadvertently define BasicObject on 1.8", :if => RUBY_VERSION.to_f < 1.9 do
+      expect(defined?(::BasicObject)).to be nil
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/test_double_spec.rb b/rspec-mocks/spec/rspec/mocks/test_double_spec.rb
new file mode 100644
index 0000000..a260d35
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/test_double_spec.rb
@@ -0,0 +1,53 @@
+module RSpec
+  module Mocks
+    RSpec.describe TestDouble do
+      describe "#freeze" do
+        subject { double }
+
+        it "gives a warning" do
+          expect(RSpec).to receive(:warn_with).with(/freeze a test double/)
+          subject.freeze
+        end
+
+        it "gives the correct call site for the warning" do
+          expect_warning_with_call_site(__FILE__, __LINE__+1)
+          subject.freeze
+        end
+
+        it "doesn't freeze the object" do
+          allow(RSpec).to receive(:warn_with).with(/freeze a test double/)
+          double.freeze
+          allow(subject).to receive(:hi)
+
+          expect {
+            subject.hi
+          }.not_to raise_error
+        end
+      end
+
+      RSpec.shared_examples_for "a copy method" do |method|
+        it "copies the `as_null_object` state when #{method}'d" do
+          dbl = double.as_null_object
+          copy = dbl.__send__(method)
+          expect(copy.foo.bar).to be(copy)
+        end
+      end
+
+      include_examples "a copy method", :dup
+      include_examples "a copy method", :clone
+
+      [[:should, :expect], [:expect], [:should]].each do |syntax|
+        context "with syntax #{syntax.inspect}" do
+          include_context "with syntax", syntax
+
+          it 'stubs the methods passed in the stubs hash' do
+            dbl = double("MyDouble", :a => 5, :b => 10)
+
+            expect(dbl.a).to eq(5)
+            expect(dbl.b).to eq(10)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/thrice_counts_spec.rb b/rspec-mocks/spec/rspec/mocks/thrice_counts_spec.rb
new file mode 100644
index 0000000..478812b
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/thrice_counts_spec.rb
@@ -0,0 +1,72 @@
+module RSpec
+  module Mocks
+    RSpec.describe "#thrice" do
+      before(:each) do
+        @double = double("test double")
+      end
+
+      it "passes when called thrice" do
+        expect(@double).to receive(:do_something).thrice
+        3.times { @double.do_something }
+        verify @double
+      end
+
+      it "passes when called thrice with specified args" do
+        expect(@double).to receive(:do_something).thrice.with("1", 1)
+        3.times { @double.do_something("1", 1) }
+        verify @double
+      end
+
+      it "passes when called thrice with unspecified args" do
+        expect(@double).to receive(:do_something).thrice
+        @double.do_something("1")
+        @double.do_something(1)
+        @double.do_something(nil)
+        verify @double
+      end
+
+      it "fails fast when call count is higher than expected" do
+        expect(@double).to receive(:do_something).thrice
+        3.times { @double.do_something }
+        expect {
+          @double.do_something
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails when call count is lower than expected" do
+        expect(@double).to receive(:do_something).thrice
+        @double.do_something
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails when called with wrong args on the first call" do
+        expect(@double).to receive(:do_something).thrice.with("1", 1)
+        expect {
+          @double.do_something(1, "1")
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+        reset @double
+      end
+
+      it "fails when called with wrong args on the second call" do
+        expect(@double).to receive(:do_something).thrice.with("1", 1)
+        @double.do_something("1", 1)
+        expect {
+          @double.do_something(1, "1")
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+        reset @double
+      end
+
+      it "fails when called with wrong args on the third call" do
+        expect(@double).to receive(:do_something).thrice.with("1", 1)
+        @double.do_something("1", 1)
+        @double.do_something("1", 1)
+        expect {
+          @double.do_something(1, "1")
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+        reset @double
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/to_ary_spec.rb b/rspec-mocks/spec/rspec/mocks/to_ary_spec.rb
new file mode 100644
index 0000000..3a9833a
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/to_ary_spec.rb
@@ -0,0 +1,52 @@
+RSpec.describe "a double receiving to_ary" do
+  shared_examples "to_ary" do
+    it "can be overridden with a stub" do
+      allow(obj).to receive(:to_ary) { :non_nil_value }
+      expect(obj.to_ary).to be(:non_nil_value)
+    end
+
+    it "responds when overriden" do
+      allow(obj).to receive(:to_ary) { :non_nil_value }
+      expect(obj).to respond_to(:to_ary)
+    end
+
+    it "supports Array#flatten" do
+      dbl = double('foo')
+      expect([dbl].flatten).to eq([dbl])
+    end
+  end
+
+  context "double as_null_object" do
+    let(:obj) { double('obj').as_null_object }
+    include_examples "to_ary"
+
+    it "does respond to to_ary" do
+      expect(obj).to respond_to(:to_ary)
+    end
+
+    it "does respond to to_a" do
+      expect(obj).to respond_to(:to_a)
+    end
+
+    it "returns nil" do
+      expect(obj.to_ary).to eq nil
+    end
+  end
+
+  context "double without as_null_object" do
+    let(:obj) { double('obj') }
+    include_examples "to_ary"
+
+    it "doesn't respond to to_ary" do
+      expect(obj).not_to respond_to(:to_ary)
+    end
+
+    it "doesn't respond to to_a", :if => ( RUBY_VERSION.to_f > 1.8 ) do
+      expect(obj).not_to respond_to(:to_a)
+    end
+
+    it "raises " do
+      expect { obj.to_ary }.to raise_error(NoMethodError)
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/twice_counts_spec.rb b/rspec-mocks/spec/rspec/mocks/twice_counts_spec.rb
new file mode 100644
index 0000000..556fcd2
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/twice_counts_spec.rb
@@ -0,0 +1,64 @@
+module RSpec
+  module Mocks
+    RSpec.describe "#twice" do
+      before(:each) do
+        @double = double("test double")
+      end
+
+      it "passes when called twice" do
+        expect(@double).to receive(:do_something).twice
+        @double.do_something
+        @double.do_something
+        verify @double
+      end
+
+      it "passes when called twice with specified args" do
+        expect(@double).to receive(:do_something).twice.with("1", 1)
+        @double.do_something("1", 1)
+        @double.do_something("1", 1)
+        verify @double
+      end
+
+      it "passes when called twice with unspecified args" do
+        expect(@double).to receive(:do_something).twice
+        @double.do_something("1")
+        @double.do_something(1)
+        verify @double
+      end
+
+      it "fails fast when call count is higher than expected" do
+        expect(@double).to receive(:do_something).twice
+        @double.do_something
+        @double.do_something
+        expect {
+          @double.do_something
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails when call count is lower than expected" do
+        expect(@double).to receive(:do_something).twice
+        @double.do_something
+        expect {
+          verify @double
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+      end
+
+      it "fails when called with wrong args on the first call" do
+        expect(@double).to receive(:do_something).twice.with("1", 1)
+        expect {
+          @double.do_something(1, "1")
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+        reset @double
+      end
+
+      it "fails when called with wrong args on the second call" do
+        expect(@double).to receive(:do_something).twice.with("1", 1)
+        @double.do_something("1", 1)
+        expect {
+          @double.do_something(1, "1")
+        }.to raise_error(RSpec::Mocks::MockExpectationError)
+        reset @double
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/class_double_with_class_loaded_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/class_double_with_class_loaded_spec.rb
new file mode 100644
index 0000000..4ecd879
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/class_double_with_class_loaded_spec.rb
@@ -0,0 +1,160 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'A class double with the doubled class loaded' do
+      include_context "with isolated configuration"
+
+      before do
+        RSpec::Mocks.configuration.verify_doubled_constant_names = true
+      end
+
+      it 'only allows class methods that exist to be stubbed' do
+        o = class_double('LoadedClass', :defined_class_method => 1)
+        expect(o.defined_class_method).to eq(1)
+
+        prevents { allow(o).to receive(:undefined_instance_method) }
+        prevents { allow(o).to receive(:defined_instance_method) }
+      end
+
+      it 'only allows class methods that exist to be expected' do
+        o = class_double('LoadedClass')
+        expect(o).to receive(:defined_class_method)
+        o.defined_class_method
+
+        prevents { expect(o).to receive(:undefined_instance_method) }
+        prevents { expect(o).to receive(:defined_instance_method) }
+        prevents { expect(o).to receive(:undefined_instance_method) }
+        prevents { expect(o).to receive(:defined_instance_method) }
+      end
+
+      it 'gives a descriptive error message for NoMethodError' do
+        o = class_double("LoadedClass")
+        expect {
+          o.defined_private_class_method
+        }.to raise_error(NoMethodError, /Double "LoadedClass"/)
+      end
+
+      it 'checks that stubbed methods are invoked with the correct arity' do
+        o = class_double('LoadedClass', :defined_class_method => 1)
+        expect {
+          o.defined_class_method(:a)
+        }.to raise_error(ArgumentError)
+      end
+
+      it 'allows dynamically defined class method stubs with arguments' do
+        o = class_double('LoadedClass')
+        allow(o).to receive(:dynamic_class_method).with(:a) { 1 }
+
+        expect(o.dynamic_class_method(:a)).to eq(1)
+      end
+
+      it 'allows dynamically defined class method mocks with arguments' do
+        o = class_double('LoadedClass')
+        expect(o).to receive(:dynamic_class_method).with(:a)
+
+        o.dynamic_class_method(:a)
+      end
+
+      it 'allows dynamically defined class methods to be expected' do
+        o = class_double('LoadedClass', :dynamic_class_method => 1)
+        expect(o.dynamic_class_method).to eq(1)
+      end
+
+      it 'allows class to be specified by constant' do
+        o = class_double(LoadedClass, :defined_class_method => 1)
+        expect(o.defined_class_method).to eq(1)
+      end
+
+      it 'can replace existing constants for the duration of the test' do
+        original = LoadedClass
+        object = class_double('LoadedClass').as_stubbed_const
+        expect(object).to receive(:defined_class_method)
+
+        expect(LoadedClass).to eq(object)
+        ::RSpec::Mocks.teardown
+        ::RSpec::Mocks.setup
+        expect(LoadedClass).to eq(original)
+      end
+
+      it 'can transfer nested constants to the double' do
+        class_double("LoadedClass").
+          as_stubbed_const(:transfer_nested_constants => true)
+        expect(LoadedClass::M).to eq(:m)
+        expect(LoadedClass::N).to eq(:n)
+      end
+
+      it 'correctly verifies expectations when constant is removed' do
+        dbl1 = class_double(LoadedClass::Nested).as_stubbed_const
+        class_double(LoadedClass).as_stubbed_const
+
+        prevents {
+          expect(dbl1).to receive(:undefined_class_method)
+        }
+      end
+
+      it 'only allows defined methods for null objects' do
+        o = class_double('LoadedClass').as_null_object
+
+        expect(o.defined_class_method).to eq(o)
+        prevents { o.undefined_method }
+      end
+
+      it 'verifies arguments for null objects' do
+        o = class_double('LoadedClass').as_null_object
+
+        expect {
+          o.defined_class_method(:too, :many, :args)
+        }.to raise_error(ArgumentError, "Wrong number of arguments. Expected 0, got 3.")
+      end
+
+      it 'validates `with` args against the method signature when stubbing a method' do
+        dbl = class_double(LoadedClass)
+        prevents(/Wrong number of arguments. Expected 0, got 2./) {
+          allow(dbl).to receive(:defined_class_method).with(2, :args)
+        }
+      end
+
+      context "when given an anonymous class" do
+        it 'properly verifies' do
+          subclass = Class.new(LoadedClass)
+          o = class_double(subclass)
+          allow(o).to receive(:defined_class_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+      end
+
+      context "when given a class that has an overriden `#name` method" do
+        it "properly verifies" do
+          check_verification class_double(LoadedClassWithOverridenName)
+        end
+
+        it "can still stub the const" do
+          class_double(LoadedClassWithOverridenName).as_stubbed_const
+          check_verification LoadedClassWithOverridenName
+        end
+
+        def check_verification(o)
+          allow(o).to receive(:defined_class_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+      end
+
+      context "when the class const has been previously stubbed" do
+        before { stub_const("LoadedClass", Class.new) }
+
+        it "uses the original class to verify against for `class_double('ClassName')`" do
+          o = class_double("LoadedClass")
+          allow(o).to receive(:defined_class_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+
+        it "uses the original class to verify against for `instance_double(ClassName)`" do
+          o = class_double(LoadedClass)
+          allow(o).to receive(:defined_class_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/class_double_with_class_not_loaded_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/class_double_with_class_not_loaded_spec.rb
new file mode 100644
index 0000000..c551719
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/class_double_with_class_not_loaded_spec.rb
@@ -0,0 +1,72 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'A class double with the doubled class not loaded' do
+      include_context "with isolated configuration"
+
+      before do
+        RSpec::Mocks.configuration.verify_doubled_constant_names = false
+      end
+
+      it 'includes the double name in errors for unexpected messages' do
+        o = class_double("NonLoadedClass")
+        expect {
+          o.foo
+        }.to fail_matching('Double "NonLoadedClass"')
+      end
+
+      it 'allows any method to be stubbed' do
+        o = class_double('NonloadedClass')
+        allow(o).to receive(:undefined_instance_method).with(:arg).and_return(1)
+        expect(o.undefined_instance_method(:arg)).to eq(1)
+      end
+
+      specify "trying to raise a class_double raises a TypeError", :unless => RUBY_VERSION == '1.9.2' do
+        subject = Object.new
+        class_double("StubbedError").as_stubbed_const
+        allow(subject).to receive(:some_method).and_raise(StubbedError)
+        expect { subject.some_method }.to raise_error(TypeError, 'exception class/object expected')
+      end
+
+      context "when stubbing a private module method" do
+        before(:all) do
+          Module.class_exec do
+            private
+            def use; end
+          end
+        end
+
+        after(:all) do
+          Module.class_exec do
+            undef use
+          end
+        end
+
+        it 'can mock private module methods' do
+          double = Module.new
+          allow(double).to receive(:use)
+          expect { double.use }.to raise_error(/private method `use' called/)
+
+          double = class_double("NonloadedClass")
+          expect(double).to receive(:use).and_return(:ok)
+          expect(double.use).to be(:ok)
+        end
+      end
+
+      context "when the class const has been previously stubbed" do
+        before { stub_const("NonLoadedClass", Class.new) }
+
+        it "treats the class as being unloaded for `class_double('NonLoadedClass')`" do
+          o = class_double("NonLoadedClass")
+          allow(o).to receive(:undefined_method)
+        end
+
+        it "treats the class as being unloaded for `instance_double(NonLoadedClass)`" do
+          o = class_double(NonLoadedClass)
+          allow(o).to receive(:undefined_method)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/construction_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/construction_spec.rb
new file mode 100644
index 0000000..a40df67
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/construction_spec.rb
@@ -0,0 +1,130 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'Constructing a verifying double' do
+      include_context 'with isolated configuration'
+
+      class ClassThatDynamicallyDefinesMethods
+        def self.define_attribute_methods!
+          define_method(:some_method_defined_dynamically) { true }
+        end
+      end
+
+      module CustomModule
+      end
+
+      describe 'instance doubles' do
+        it 'cannot be constructed with a non-module object' do
+          expect {
+            instance_double(Object.new)
+          }.to raise_error(/Module or String expected/)
+        end
+
+        it 'can be constructed with a struct' do
+          o = instance_double(Struct.new(:defined_method), :defined_method => 1)
+          expect(o.defined_method).to eq(1)
+        end
+
+        it 'allows named constants to be looked up and declared to verifying double callbacks' do
+          expect { |probe|
+            RSpec.configuration.mock_with(:rspec) do |config|
+              config.verify_doubled_constant_names = true
+              config.when_declaring_verifying_double(&probe)
+            end
+
+            instance_double("RSpec::Mocks::ClassThatDynamicallyDefinesMethods")
+          }.to yield_with_args(have_attributes :target => ClassThatDynamicallyDefinesMethods)
+        end
+
+        it 'allows anonymous constants to be looked up and declared to verifying double callbacks' do
+          anonymous_module = Module.new
+          expect { |probe|
+            RSpec.configuration.mock_with(:rspec) do |config|
+              config.verify_doubled_constant_names = true
+              config.when_declaring_verifying_double(&probe)
+            end
+
+            instance_double(anonymous_module)
+          }.to yield_with_args(have_attributes :target => anonymous_module)
+        end
+
+        it 'allows classes to be customised' do
+          test_class = Class.new(ClassThatDynamicallyDefinesMethods)
+
+          RSpec.configuration.mock_with(:rspec) do |config|
+            config.when_declaring_verifying_double do |reference|
+              reference.target.define_attribute_methods!
+            end
+          end
+
+          instance_double(test_class, :some_method_defined_dynamically => true)
+        end
+      end
+
+      describe 'class doubles' do
+        it 'cannot be constructed with a non-module object' do
+          expect {
+            class_double(Object.new)
+          }.to raise_error(/Module or String expected/)
+        end
+
+        it 'declares named modules to verifying double callbacks' do
+          expect { |probe|
+            RSpec.configuration.mock_with(:rspec) do |config|
+              config.when_declaring_verifying_double(&probe)
+            end
+            class_double CustomModule
+          }.to yield_with_args(have_attributes :target => CustomModule)
+        end
+
+        it 'declares anonymous modules to verifying double callbacks' do
+          anonymous_module = Module.new
+          expect { |probe|
+            RSpec.configuration.mock_with(:rspec) do |config|
+              config.when_declaring_verifying_double(&probe)
+            end
+            class_double anonymous_module
+          }.to yield_with_args(have_attributes :target => anonymous_module)
+        end
+      end
+
+      describe 'object doubles' do
+        it 'declares the class to verifying double callbacks' do
+          object = Object.new
+
+          expect { |probe|
+            RSpec.configuration.mock_with(:rspec) do |config|
+              config.when_declaring_verifying_double(&probe)
+            end
+            object_double object
+          }.to yield_with_args(have_attributes :target => object)
+        end
+      end
+
+      describe 'when verify_doubled_constant_names config option is set' do
+
+        before do
+          RSpec::Mocks.configuration.verify_doubled_constant_names = true
+        end
+
+        it 'prevents creation of instance doubles for unloaded constants' do
+          expect {
+            instance_double('LoadedClas')
+          }.to raise_error(VerifyingDoubleNotDefinedError)
+        end
+
+        it 'prevents creation of class doubles for unloaded constants' do
+          expect {
+            class_double('LoadedClas')
+          }.to raise_error(VerifyingDoubleNotDefinedError)
+        end
+      end
+
+      it 'can only be named with a string or a module' do
+        expect { instance_double(1) }.to raise_error(ArgumentError)
+        expect { instance_double(nil) }.to raise_error(ArgumentError)
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/expected_arg_verification_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/expected_arg_verification_spec.rb
new file mode 100644
index 0000000..574d718
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/expected_arg_verification_spec.rb
@@ -0,0 +1,128 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'Expected argument verification (when `#with` is called)' do
+      # Note: these specs here aren't meant to be exhaustive. The specs in
+      # rspec-support for the method signature verifier are. Here we are just
+      # covering the code paths within the `with` implementation, including
+      # the special handling for `any_args` and `no_args`.
+      context "when doubling an unloaded class" do
+        it 'allows any arguments' do
+          expect(defined?(UnloadedClass)).to be_falsey
+          inst_dbl = instance_double("UnloadedClass")
+
+          expect {
+            expect(inst_dbl).to receive(:message).with(:foo, :bar, :bazz)
+          }.not_to raise_error
+
+          reset inst_dbl
+        end
+      end
+
+      context "when doubling a loaded class" do
+        let(:dbl) { instance_double(LoadedClass) }
+        after { reset dbl }
+
+        context "when `any_args` is used" do
+          context "as the only argument" do
+            it "is allowed regardless of how many args the method requires" do
+              expect {
+                expect(dbl).to receive(:instance_method_with_two_args).with(any_args)
+              }.not_to raise_error
+            end
+          end
+
+          context "as the first argument, with too many additional args" do
+            it "is disallowed" do
+              expect {
+                expect(dbl).to receive(:instance_method_with_two_args).with(any_args, 1, 2, 3)
+              }.to fail_with("Wrong number of arguments. Expected 2, got 3.")
+            end
+          end
+
+          context "as the first argument, with an allowed number of additional args" do
+            it "is allowed" do
+              expect {
+                expect(dbl).to receive(:instance_method_with_two_args).with(any_args, 1, 2)
+              }.not_to raise_error
+
+              expect {
+                expect(dbl).to receive(:instance_method_with_two_args).with(any_args, 1)
+              }.not_to raise_error
+            end
+          end
+        end
+
+        context "when `no_args` is used" do
+          it "allows a method expectation on a method that accepts no arguments" do
+            expect(LoadedClass.instance_method(:defined_instance_method).arity).to eq(0)
+
+            expect {
+              expect(dbl).to receive(:defined_instance_method).with(no_args)
+            }.not_to raise_error
+          end
+
+          it "allows a method expectation on a method that has defaults for all arguments" do
+            expect {
+              expect(dbl).to receive(:instance_method_with_only_defaults).with(no_args)
+            }.not_to raise_error
+          end
+
+          it "does not allow a method expectation on a method that has required arguments" do
+            expect {
+              expect(dbl).to receive(:instance_method_with_two_args).with(no_args)
+            }.to fail_with("Wrong number of arguments. Expected 2, got 0.")
+          end
+
+          if RSpec::Support::RubyFeatures.required_kw_args_supported?
+            context "for a method with required keyword args" do
+              it 'covers the required args when `any_args` is last' do
+                expect {
+                  expect(dbl).to receive(:kw_args_method).with(1, any_args)
+                }.not_to raise_error
+              end
+
+              it 'does not cover the required args when there are args after `any_args`' do
+                expect {
+                  # Use eval to avoid syntax error on 1.8 and 1.9
+                  eval("expect(dbl).to receive(:kw_args_method).with(any_args, optional_arg: 3)")
+                }.to fail_with("Missing required keyword arguments: required_arg")
+              end
+            end
+          end
+        end
+
+        if RSpec::Support::RubyFeatures.required_kw_args_supported?
+          it 'does not cover required args when `any_args` is not used' do
+            expect {
+              expect(dbl).to receive(:kw_args_method).with(anything)
+            }.to fail_with("Missing required keyword arguments: required_arg")
+          end
+        end
+
+        context "when a list of args is provided" do
+          it "allows a method expectation when the arity matches" do
+            expect {
+              expect(dbl).to receive(:instance_method_with_two_args).with(1, 2)
+            }.not_to raise_error
+          end
+
+          it "does not allow a method expectation with an arity mismatch" do
+            expect {
+              expect(dbl).to receive(:instance_method_with_two_args).with(1, 2, 3)
+            }.to fail_with("Wrong number of arguments. Expected 2, got 3.")
+          end
+        end
+
+        context "when `with` is called with no args" do
+          it "fails with an error suggesting the user use `no_args` instead" do
+            expect {
+              expect(dbl).to receive(:instance_method_with_two_args).with
+            }.to raise_error(ArgumentError, /no_args/)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/instance_double_with_class_loaded_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/instance_double_with_class_loaded_spec.rb
new file mode 100644
index 0000000..c0b1bb3
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/instance_double_with_class_loaded_spec.rb
@@ -0,0 +1,218 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'An instance double with the doubled class loaded' do
+      include_context "with isolated configuration"
+
+      before do
+        RSpec::Mocks.configuration.verify_doubled_constant_names = true
+      end
+
+      it 'only allows instance methods that exist to be stubbed' do
+        o = instance_double('LoadedClass', :defined_instance_method => 1)
+        expect(o.defined_instance_method).to eq(1)
+
+        prevents { allow(o).to receive(:undefined_instance_method) }
+        prevents { allow(o).to receive(:defined_class_method) }
+      end
+
+      it 'only allows instance methods that exist to be expected' do
+        o = instance_double('LoadedClass')
+        expect(o).to receive(:defined_instance_method)
+        o.defined_instance_method
+
+        prevents { expect(o).to receive(:undefined_instance_method) }
+        prevents { expect(o).to receive(:defined_class_method) }
+        prevents { expect(o).to receive(:undefined_instance_method) }
+        prevents { expect(o).to receive(:defined_class_method) }
+      end
+
+      it 'allows `send` to be stubbed if it is defined on the class' do
+        o = instance_double('LoadedClass')
+        allow(o).to receive(:send).and_return("received")
+        expect(o.send(:msg)).to eq("received")
+      end
+
+      it 'gives a descriptive error message for NoMethodError' do
+        o = instance_double("LoadedClass")
+        expect {
+          o.defined_private_method
+        }.to raise_error(NoMethodError,
+                           /Double "LoadedClass \(instance\)"/)
+      end
+
+      it 'does not allow dynamic methods to be expected' do
+        # This isn't possible at the moment since an instance of the class
+        # would be required for the verification, and we only have the
+        # class itself.
+        #
+        # This spec exists as "negative" documentation of the absence of a
+        # feature, to highlight the asymmetry from class doubles (that do
+        # support this behaviour).
+        prevents {
+          instance_double('LoadedClass', :dynamic_instance_method => 1)
+        }
+      end
+
+      it 'checks the arity of stubbed methods' do
+        o = instance_double('LoadedClass')
+        prevents {
+          expect(o).to receive(:defined_instance_method).with(:a)
+        }
+      end
+
+      it 'checks that stubbed methods are invoked with the correct arity' do
+        o = instance_double('LoadedClass', :defined_instance_method => 25)
+        expect {
+          o.defined_instance_method(:a)
+        }.to raise_error(ArgumentError,
+                           "Wrong number of arguments. Expected 0, got 1.")
+      end
+
+      if required_kw_args_supported?
+        it 'allows keyword arguments' do
+          o = instance_double('LoadedClass', :kw_args_method => true)
+          expect(o.kw_args_method(1, :required_arg => 'something')).to eq(true)
+        end
+
+        context 'for a method that only accepts keyword args' do
+          it 'allows hash matchers like `hash_including` to be used in place of the keywords arg hash' do
+            o = instance_double('LoadedClass')
+            expect(o).to receive(:kw_args_method).
+              with(1, hash_including(:required_arg => 1))
+            o.kw_args_method(1, :required_arg => 1)
+          end
+
+          it 'allows anything matcher to be used in place of the keywords arg hash' do
+            o = instance_double('LoadedClass')
+            expect(o).to receive(:kw_args_method).with(1, anything)
+            o.kw_args_method(1, :required_arg => 1)
+          end
+
+          it 'still checks positional arguments when matchers used for keyword args' do
+            o = instance_double('LoadedClass')
+            prevents(/Expected 1, got 3/) {
+              expect(o).to receive(:kw_args_method).
+                with(1, 2, 3, hash_including(:required_arg => 1))
+            }
+          end
+
+          it 'does not allow matchers to be used in an actual method call' do
+            o = instance_double('LoadedClass')
+            matcher = hash_including(:required_arg => 1)
+            allow(o).to receive(:kw_args_method).with(1, matcher)
+            expect {
+              o.kw_args_method(1, matcher)
+            }.to raise_error(ArgumentError)
+          end
+        end
+
+        context 'for a method that accepts a mix of optional keyword and positional args' do
+          it 'allows hash matchers like `hash_including` to be used in place of the keywords arg hash' do
+            o = instance_double('LoadedClass')
+            expect(o).to receive(:mixed_args_method).with(1, 2, hash_including(:optional_arg_1 => 1))
+            o.mixed_args_method(1, 2, :optional_arg_1 => 1)
+          end
+        end
+
+        it 'checks that stubbed methods with required keyword args are ' +
+           'invoked with the required arguments' do
+          o = instance_double('LoadedClass', :kw_args_method => true)
+          expect {
+            o.kw_args_method(:optional_arg => 'something')
+          }.to raise_error(ArgumentError)
+        end
+      end
+
+      it 'validates `with` args against the method signature when stubbing a method' do
+        dbl = instance_double(LoadedClass)
+        prevents(/Wrong number of arguments. Expected 2, got 3./) {
+          allow(dbl).to receive(:instance_method_with_two_args).with(3, :foo, :args)
+        }
+      end
+
+      it 'allows class to be specified by constant' do
+        o = instance_double(LoadedClass, :defined_instance_method => 1)
+        expect(o.defined_instance_method).to eq(1)
+      end
+
+      context "when the class const has been previously stubbed" do
+        before { class_double(LoadedClass).as_stubbed_const }
+
+        it "uses the original class to verify against for `instance_double('LoadedClass')`" do
+          o = instance_double("LoadedClass")
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+
+        it "uses the original class to verify against for `instance_double(LoadedClass)`" do
+          o = instance_double(LoadedClass)
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+      end
+
+      context "when given a class that has an overriden `#name` method" do
+        it "properly verifies" do
+          o = instance_double(LoadedClassWithOverridenName)
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+      end
+
+      context 'for null objects' do
+        let(:obj) { instance_double('LoadedClass').as_null_object }
+
+        it 'only allows defined methods' do
+          expect(obj.defined_instance_method).to eq(obj)
+          prevents { obj.undefined_method }
+          prevents { obj.send(:undefined_method) }
+          prevents { obj.__send__(:undefined_method) }
+        end
+
+        it 'verifies arguments' do
+          expect {
+            obj.defined_instance_method(:too, :many, :args)
+          }.to raise_error(ArgumentError, "Wrong number of arguments. Expected 0, got 3.")
+        end
+
+        it "includes the double's name in a private method error" do
+          expect {
+            obj.rand
+          }.to raise_error(NoMethodError, %r{private.*Double "LoadedClass \(instance\)"})
+        end
+
+        it 'reports what public messages it responds to accurately' do
+          expect(obj.respond_to?(:defined_instance_method)).to be true
+          expect(obj.respond_to?(:defined_instance_method, true)).to be true
+          expect(obj.respond_to?(:defined_instance_method, false)).to be true
+
+          expect(obj.respond_to?(:undefined_method)).to be false
+          expect(obj.respond_to?(:undefined_method, true)).to be false
+          expect(obj.respond_to?(:undefined_method, false)).to be false
+        end
+
+        it 'reports that it responds to defined private methods when the appropriate arg is passed' do
+          expect(obj.respond_to?(:defined_private_method)).to be false
+          expect(obj.respond_to?(:defined_private_method, true)).to be true
+          expect(obj.respond_to?(:defined_private_method, false)).to be false
+        end
+
+        if RUBY_VERSION.to_f < 2.0 # respond_to?(:protected_method) changed behavior in Ruby 2.0.
+          it 'reports that it responds to protected methods' do
+            expect(obj.respond_to?(:defined_protected_method)).to be true
+            expect(obj.respond_to?(:defined_protected_method, true)).to be true
+            expect(obj.respond_to?(:defined_protected_method, false)).to be true
+          end
+        else
+          it 'reports that it responds to protected methods when the appropriate arg is passed' do
+            expect(obj.respond_to?(:defined_protected_method)).to be false
+            expect(obj.respond_to?(:defined_protected_method, true)).to be true
+            expect(obj.respond_to?(:defined_protected_method, false)).to be false
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/instance_double_with_class_not_loaded_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/instance_double_with_class_not_loaded_spec.rb
new file mode 100644
index 0000000..32b97b1
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/instance_double_with_class_not_loaded_spec.rb
@@ -0,0 +1,71 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'An instance double with the doubled class not loaded' do
+      include_context "with isolated configuration"
+
+      before do
+        RSpec::Mocks.configuration.verify_doubled_constant_names = false
+      end
+
+      it 'includes the double name in errors for unexpected messages' do
+        o = instance_double("NonLoadedClass")
+        expect {
+          o.foo
+        }.to fail_matching('Double "NonLoadedClass (instance)"')
+      end
+
+      it 'allows any instance method to be stubbed' do
+        o = instance_double('NonloadedClass')
+        allow(o).to receive(:undefined_instance_method).with(:arg).and_return(true)
+        expect(o.undefined_instance_method(:arg)).to eq(true)
+      end
+
+      it 'allows any instance method to be expected' do
+        o = instance_double("NonloadedClass")
+
+        expect(o).to receive(:undefined_instance_method).
+                       with(:arg).
+                       and_return(true)
+
+        expect(o.undefined_instance_method(:arg)).to eq(true)
+      end
+
+      it 'handles classes that are materialized after mocking' do
+        stub_const "A::B", Object.new
+        o = instance_double "A", :undefined_instance_method => true
+
+        expect(o.undefined_instance_method).to eq(true)
+      end
+
+      context 'for null objects' do
+        let(:obj) { instance_double('NonLoadedClass').as_null_object }
+
+        it 'returns self from any message' do
+          expect(obj.a.b.c).to be(obj)
+        end
+
+        it 'reports it responds to any message' do
+          expect(obj.respond_to?(:a)).to be true
+          expect(obj.respond_to?(:a, false)).to be true
+          expect(obj.respond_to?(:a, true)).to be true
+        end
+      end
+
+      context "when the class const has been previously stubbed" do
+        before { class_double("NonLoadedClass").as_stubbed_const }
+
+        it "treats the class as unloaded for `instance_double('NonLoadedClass')`" do
+          o = instance_double("NonLoadedClass")
+          allow(o).to receive(:undefined_method)
+        end
+
+        it "treats the class as unloaded for `instance_double(NonLoadedClass)`" do
+          o = instance_double(NonLoadedClass)
+          allow(o).to receive(:undefined_method)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/method_visibility_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/method_visibility_spec.rb
new file mode 100644
index 0000000..e975243
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/method_visibility_spec.rb
@@ -0,0 +1,129 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe "Method visibility for verified doubles" do
+      include_context "with isolated configuration"
+
+      before do
+        RSpec::Mocks.configuration.verify_doubled_constant_names = true
+      end
+
+      context "for an instance double (when the class is loaded)" do
+        shared_examples "preserves method visibility" do |visibility|
+          method_name = :"defined_#{visibility}_method"
+
+          it "can allow a #{visibility} instance method" do
+            o = instance_double('LoadedClass')
+            allow(o).to receive(method_name).and_return(3)
+            expect(o.send method_name).to eq(3)
+          end
+
+          it "can expect a #{visibility} instance method" do
+            o = instance_double('LoadedClass')
+            expect(o).to receive(method_name)
+            o.send method_name
+          end
+
+          it "preserves #{visibility} visibility when allowing a #{visibility} method" do
+            preserves_visibility(method_name, visibility) do
+              instance_double('LoadedClass').tap do |o|
+                allow(o).to receive(method_name)
+              end
+            end
+          end
+
+          it "preserves #{visibility} visibility when expecting a #{visibility} method" do
+            preserves_visibility(method_name, visibility) do
+              instance_double('LoadedClass').tap do |o|
+                expect(o).to receive(method_name).at_least(:once)
+                o.send(method_name) # to satisfy the expectation
+              end
+            end
+          end
+
+          it "preserves #{visibility} visibility on a null object" do
+            preserves_visibility(method_name, visibility) do
+              instance_double('LoadedClass').as_null_object
+            end
+          end
+        end
+
+        include_examples "preserves method visibility", :private
+        include_examples "preserves method visibility", :protected
+      end
+
+      context "for a class double (when the class is loaded)" do
+        shared_examples "preserves method visibility" do |visibility|
+          method_name = :"defined_#{visibility}_class_method"
+
+          it "can allow a #{visibility} instance method" do
+            o = class_double('LoadedClass')
+            allow(o).to receive(method_name).and_return(3)
+            expect(o.send method_name).to eq(3)
+          end
+
+          it "can expect a #{visibility} instance method" do
+            o = class_double('LoadedClass')
+            expect(o).to receive(method_name)
+            o.send method_name
+          end
+
+          it "preserves #{visibility} visibility when allowing a #{visibility} method" do
+            preserves_visibility(method_name, visibility) do
+              class_double('LoadedClass').tap do |o|
+                allow(o).to receive(method_name)
+              end
+            end
+          end
+
+          it "preserves #{visibility} visibility when expecting a #{visibility} method" do
+            preserves_visibility(method_name, visibility) do
+              class_double('LoadedClass').tap do |o|
+                expect(o).to receive(method_name).at_least(:once)
+                o.send(method_name) # to satisfy the expectation
+              end
+            end
+          end
+
+          it "preserves #{visibility} visibility on a null object" do
+            preserves_visibility(method_name, visibility) do
+              class_double('LoadedClass').as_null_object
+            end
+          end
+        end
+
+        include_examples "preserves method visibility", :private
+        include_examples "preserves method visibility", :protected
+      end
+
+      def preserves_visibility(method_name, visibility)
+        double = yield
+
+        expect {
+          # send bypasses visbility, so we use eval instead.
+          eval("double.#{method_name}")
+        }.to raise_error(NoMethodError, a_message_indicating_visibility_violation(method_name, visibility))
+
+        expect { double.send(method_name) }.not_to raise_error
+        expect { double.__send__(method_name) }.not_to raise_error
+
+        unless double.null_object?
+          # Null object doubles use `method_missing` and so the singleton class
+          # doesn't know what methods are defined.
+          singleton_class = class << double; self; end
+          expect(singleton_class.send("#{visibility}_method_defined?", method_name)).to be true
+        end
+      end
+
+      RSpec::Matchers.define :a_message_indicating_visibility_violation do |method_name, visibility|
+        match do |msg|
+          # This should NOT Be just `msg.match(visibility)` because the method being called
+          # has the visibility name in it. We want to ensure it's a message that ruby is
+          # stating is of the given visibility.
+          msg.match("#{visibility} ") && msg.match(method_name.to_s)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/naming_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/naming_spec.rb
new file mode 100644
index 0000000..806c787
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/naming_spec.rb
@@ -0,0 +1,83 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec::Matchers.define :fail_expectations_as do |expected|
+      description { "include a meaningful name in the exception" }
+
+      def error_message_for(verifying_double)
+        expect(actual).to have_received(:defined_instance_and_class_method)
+      rescue MockExpectationError, Expectations::ExpectationNotMetError => e
+        e.message
+      else
+        raise("should have failed but did not")
+      end
+
+      failure_message do |actual|
+        "expected #{actual.inspect} to fail expecations as:\n" +
+          "  #{expected.inspect}, but failed with:\n" +
+          "  #{@error_message.inspect}"
+      end
+
+      match do |actual|
+        @error_message = error_message_for(actual)
+        @error_message.include?(expected)
+      end
+    end
+
+    RSpec.describe 'Verified double naming' do
+      shared_examples "a named verifying double" do |default_name|
+        context "when a name is given as a string" do
+          subject { create_double("LoadedClass", "foo") }
+          it { is_expected.to fail_expectations_as('Double "foo"') }
+        end
+
+        context "when a name is given as a symbol" do
+          subject { create_double("LoadedClass", :foo) }
+          it { is_expected.to fail_expectations_as('Double :foo') }
+        end
+
+        context "when no name is given" do
+          subject { create_double("LoadedClass") }
+          it { is_expected.to fail_expectations_as("Double \"#{default_name}\"") }
+        end
+      end
+
+      describe "instance_double" do
+        it_behaves_like "a named verifying double", "LoadedClass (instance)" do
+          alias :create_double :instance_double
+        end
+      end
+
+      describe "instance_spy" do
+        it_behaves_like "a named verifying double", "LoadedClass (instance)" do
+          alias :create_double :instance_spy
+        end
+      end
+
+      describe "class_double" do
+        it_behaves_like "a named verifying double", "LoadedClass" do
+          alias :create_double :class_double
+        end
+      end
+
+      describe "class_spy" do
+        it_behaves_like "a named verifying double", "LoadedClass" do
+          alias :create_double :class_spy
+        end
+      end
+
+      describe "object_double" do
+        it_behaves_like "a named verifying double", "LoadedClass" do
+          alias :create_double :object_double
+        end
+      end
+
+      describe "object_spy" do
+        it_behaves_like "a named verifying double", "LoadedClass" do
+          alias :create_double :object_spy
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks/verifying_doubles/object_double_spec.rb b/rspec-mocks/spec/rspec/mocks/verifying_doubles/object_double_spec.rb
new file mode 100644
index 0000000..9694e75
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks/verifying_doubles/object_double_spec.rb
@@ -0,0 +1,134 @@
+require 'support/doubled_classes'
+
+module RSpec
+  module Mocks
+    RSpec.describe 'An object double' do
+      it 'can replace an unloaded constant' do
+        o = object_double("LoadedClass::NOINSTANCE").as_stubbed_const
+
+        expect(LoadedClass::NOINSTANCE).to eq(o)
+
+        expect(o).to receive(:undefined_instance_method)
+        o.undefined_instance_method
+      end
+
+      it 'can replace a constant by name and verify instance methods' do
+        o = object_double("LoadedClass::INSTANCE").as_stubbed_const
+
+        expect(LoadedClass::INSTANCE).to eq(o)
+
+        prevents { expect(o).to receive(:undefined_instance_method) }
+        prevents { expect(o).to receive(:defined_class_method) }
+        prevents { o.defined_instance_method }
+
+        expect(o).to receive(:defined_instance_method)
+        o.defined_instance_method
+        expect(o).to receive(:defined_private_method)
+        o.send :defined_private_method
+      end
+
+      it 'can create a double that matches the interface of any arbitrary object' do
+        o = object_double(LoadedClass.new)
+
+        prevents { expect(o).to receive(:undefined_instance_method) }
+        prevents { expect(o).to receive(:defined_class_method) }
+        prevents { o.defined_instance_method }
+
+        expect(o).to receive(:defined_instance_method)
+        o.defined_instance_method
+        expect(o).to receive(:defined_private_method)
+        o.send :defined_private_method
+      end
+
+      it 'does not allow transferring constants to an object' do
+        expect {
+          object_double("LoadedClass::INSTANCE").
+            as_stubbed_const(:transfer_nested_constants => true)
+        }.to raise_error(/Cannot transfer nested constants/)
+      end
+
+      it 'does not allow as_stubbed_constant for real objects' do
+        expect {
+          object_double(LoadedClass.new).as_stubbed_const
+        }.to raise_error(/Can not perform constant replacement with an anonymous object/)
+      end
+
+      it 'is not a module' do
+        expect(object_double("LoadedClass::INSTANCE")).to_not be_a(Module)
+      end
+
+      it 'validates `with` args against the method signature when stubbing a method' do
+        dbl = object_double(LoadedClass.new)
+        prevents(/Wrong number of arguments. Expected 2, got 3./) {
+          allow(dbl).to receive(:instance_method_with_two_args).with(3, :foo, :args)
+        }
+      end
+
+      context "when a loaded object constant has previously been stubbed with an object" do
+        before { stub_const("LoadedClass::INSTANCE", Object.new) }
+
+        it "uses the original object to verify against for `object_double('ConstName')`" do
+          o = object_double("LoadedClass::INSTANCE")
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_meth) }
+        end
+
+        it "uses the stubbed const value to verify against for `object_double(ConstName)`, " \
+           "which probably isn't what the user wants, but there's nothing else we can do since " \
+           "we can't get the constant name from the given object and thus cannot interrogate " \
+           "our stubbed const registry to see it has been stubbed" do
+          o = object_double(LoadedClass::INSTANCE)
+          prevents { allow(o).to receive(:defined_instance_method) }
+        end
+      end
+
+      context "when a loaded object constant has previously been stubbed with a class" do
+        before { stub_const("LoadedClass::INSTANCE", Class.new) }
+
+        it "uses the original object to verify against for `object_double('ConstName')`" do
+          o = object_double("LoadedClass::INSTANCE")
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_meth) }
+        end
+
+        it "uses the original object to verify against for `object_double(ConstName)`" do
+          o = object_double(LoadedClass::INSTANCE)
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_meth) }
+        end
+      end
+
+      context "when an unloaded object constant has previously been stubbed with an object" do
+        before { stub_const("LoadedClass::NOINSTANCE", LoadedClass::INSTANCE) }
+
+        it "treats it as being unloaded for `object_double('ConstName')`" do
+          o = object_double("LoadedClass::NOINSTANCE")
+          allow(o).to receive(:undefined_method)
+        end
+
+        it "uses the stubbed const value to verify against for `object_double(ConstName)`, " \
+           "which probably isn't what the user wants, but there's nothing else we can do since " \
+           "we can't get the constant name from the given object and thus cannot interrogate " \
+           "our stubbed const registry to see it has been stubbed" do
+          o = object_double(LoadedClass::NOINSTANCE)
+          allow(o).to receive(:defined_instance_method)
+          prevents { allow(o).to receive(:undefined_method) }
+        end
+      end
+
+      context "when an unloaded object constant has previously been stubbed with a class" do
+        before { stub_const("LoadedClass::NOINSTANCE", Class.new) }
+
+        it "treats it as being unloaded for `object_double('ConstName')`" do
+          o = object_double("LoadedClass::NOINSTANCE")
+          allow(o).to receive(:undefined_method)
+        end
+
+        it "treats it as being unloaded for `object_double('ConstName')`" do
+          o = object_double(LoadedClass::NOINSTANCE)
+          allow(o).to receive(:undefined_method)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-mocks/spec/rspec/mocks_spec.rb b/rspec-mocks/spec/rspec/mocks_spec.rb
new file mode 100644
index 0000000..5f1f540
--- /dev/null
+++ b/rspec-mocks/spec/rspec/mocks_spec.rb
@@ -0,0 +1,206 @@
+require 'rspec/support/spec/prevent_load_time_warnings'
+
+RSpec.describe RSpec::Mocks do
+  it_behaves_like 'a library that issues no warnings when loaded',
+    'rspec-mocks', 'require "rspec/mocks"',
+    # Must be required before other files due to how our autoloads are setup.
+    # (Users won't hit this problem because they won't require all the files
+    # individually in whatever order the file system returns)
+    'require "rspec/mocks/any_instance"' do
+
+    if RUBY_VERSION == '1.9.2'
+      before(:example, :description => /spec files/) do
+        pending "Loading psych and syck on 1.9.2 (as our test suite does) triggers warnings"
+      end
+    end
+  end
+
+  describe ".verify" do
+    it "delegates to the space" do
+      foo = double
+      expect(foo).to receive(:bar)
+      expect do
+        RSpec::Mocks.verify
+      end.to raise_error(RSpec::Mocks::MockExpectationError)
+
+      RSpec::Mocks.teardown # so the mocks aren't re-verified after this example
+    end
+  end
+
+  describe ".teardown" do
+    it "resets method stubs" do
+      string = "foo"
+      allow(string).to receive(:bar)
+      RSpec::Mocks.teardown
+      expect { string.bar }.to raise_error(NoMethodError)
+    end
+
+    it "does not put rspec-mocks into an inconsistent state when called extra times" do
+      RSpec::Mocks.teardown
+      RSpec::Mocks.teardown
+      RSpec::Mocks.teardown
+
+      string = "foo"
+      expect { allow(string).to receive(:bar) }.to raise_error(RSpec::Mocks::OutsideOfExampleError)
+
+      RSpec::Mocks.setup
+      allow(string).to receive(:bar).and_return(:baz)
+      expect(string.bar).to eq(:baz)
+    end
+  end
+
+  describe ".setup" do
+    it 'starts a new space scope that is later removed by .teardown' do
+      old_space = RSpec::Mocks.space
+      RSpec::Mocks.setup
+
+      new_space = RSpec::Mocks.space
+      expect(new_space).not_to equal(old_space)
+
+      RSpec::Mocks.teardown
+      expect(RSpec::Mocks.space).to equal(old_space)
+    end
+  end
+
+  describe ".configuration" do
+    it 'returns a memoized configuration instance' do
+      expect(RSpec::Mocks.configuration).to be_a(RSpec::Mocks::Configuration)
+      expect(RSpec::Mocks.configuration).to be(RSpec::Mocks.configuration)
+    end
+  end
+
+  describe ".with_temporary_scope" do
+    context "in a before(:all) with a stubbed double" do
+      before(:all) do
+        RSpec::Mocks.with_temporary_scope do
+          @calculator = double
+          allow(@calculator).to receive(:add) { |a, b| a + b }
+          @sum = @calculator.add(3, 4)
+        end
+
+        capture_error { @calculator.add(1, 10) }
+      end
+
+      it 'allows the stubbed double to be used' do
+        expect(@sum).to eq(7)
+      end
+
+      it 'does not allow the double to be used in the examples' do
+        expect {
+          @calculator.add(1, 2)
+        }.to raise_error(RSpec::Mocks::ExpiredTestDoubleError)
+      end
+
+      it 'does not allow the double to be used after the scope in before(:all)' do
+        expect(@error).to be_a(RSpec::Mocks::OutsideOfExampleError)
+      end
+    end
+
+    context "in a before(:all) with a stubbed const" do
+      before(:all) do
+        RSpec::Mocks.with_temporary_scope do
+          stub_const("ValueX", 3)
+          stub_const("ValueY", 4)
+          @sum = ValueX + ValueY
+        end
+
+        capture_error { ValueX + ValueY }
+      end
+
+      it 'allows the stubbed constants to be used' do
+        expect(@sum).to eq(7)
+      end
+
+      it 'does not allow the stubbed constants to be used in the examples' do
+        expect(defined?(ValueX)).to be_falsey
+        expect(defined?(ValueY)).to be_falsey
+      end
+
+      it 'does not allow the stubbed constants to be used after the scope in before(:all)' do
+        expect(@error).to be_a(NameError)
+        expect(@error.message).to include("ValueX")
+      end
+    end
+
+    context "in a before(:all) with a unmet mock expectation" do
+      before(:all) do
+        capture_error do
+          RSpec::Mocks.with_temporary_scope do
+            calculator = double
+            expect(calculator).to receive(:add)
+          end
+        end
+      end
+
+      it 'fails with a mock expectation error' do
+        expect(@error).to be_a(RSpec::Mocks::MockExpectationError)
+      end
+    end
+
+    context "in a before(:all) with an any_instance stub" do
+      before(:all) do
+        RSpec::Mocks.with_temporary_scope do
+          allow_any_instance_of(String).to receive(:sum_with) { |val, x| val + x }
+          @sum = "foo".sum_with("bar")
+        end
+
+        capture_error { "you".sum_with("me") }
+      end
+
+      it 'allows the stub to be used' do
+        expect(@sum).to eq("foobar")
+      end
+
+      it 'does not allow the double to be used in the examples' do
+        expect {
+          "foo".sum_with("baz")
+        }.to raise_error(NameError, /sum_with/)
+      end
+
+      it 'does not allow the double to be used after the scope in before(:all)' do
+        expect(@error).to be_a(NameError)
+        expect(@error.message).to include("sum_with")
+      end
+    end
+
+    it 'tears down even if an error occurs' do
+      foo = Object.new
+
+      expect {
+        RSpec::Mocks.with_temporary_scope do
+          allow(foo).to receive(:bar)
+          raise "boom"
+        end
+      }.to raise_error("boom")
+
+      expect(foo).not_to respond_to(:bar)
+    end
+
+    it 'does not verify if an error occurs before the block completes' do
+      expect {
+        RSpec::Mocks.with_temporary_scope do
+          foo   = Object.new
+          expect(foo).to receive(:bar)
+          raise "boom"
+        end
+      }.to raise_error("boom") # rather than MockExpectationError
+    end
+
+    def capture_error
+      yield
+    rescue Exception => @error
+    end
+  end
+
+  context "when there is a `let` declaration that overrides an argument matcher" do
+    let(:boolean) { :from_let }
+
+    before do
+      expect(RSpec::Mocks::ArgumentMatchers.method_defined?(:boolean)).to be true
+    end
+
+    it 'allows the `let` definition to win' do
+      expect(boolean).to eq(:from_let)
+    end
+  end
+end
diff --git a/rspec-mocks/spec/spec_helper.rb b/rspec-mocks/spec/spec_helper.rb
new file mode 100644
index 0000000..2b4f0d6
--- /dev/null
+++ b/rspec-mocks/spec/spec_helper.rb
@@ -0,0 +1,166 @@
+require 'rspec/support/spec'
+require 'rspec/support/ruby_features'
+
+RSpec::Support::Spec.setup_simplecov do
+  minimum_coverage 95
+end
+
+require 'yaml'
+begin
+  require 'psych'
+rescue LoadError
+end
+
+RSpec::Matchers.define :include_method do |expected|
+  match do |actual|
+    actual.map { |m| m.to_s }.include?(expected.to_s)
+  end
+end
+require 'support/matchers'
+
+module VerifyAndResetHelpers
+  def verify(object)
+    proxy = RSpec::Mocks.space.proxy_for(object)
+    proxy.verify
+  ensure
+    proxy.reset # so it doesn't fail the verify after the example completes
+  end
+
+  def reset(object)
+    RSpec::Mocks.space.proxy_for(object).reset
+  end
+
+  def verify_all
+    RSpec::Mocks.space.verify_all
+  ensure
+    reset_all
+  end
+
+  def reset_all
+    RSpec::Mocks.space.reset_all
+  end
+
+  def with_unfulfilled_double
+    d = double("double")
+    yield d
+    reset d
+  end
+end
+
+module VerificationHelpers
+  def prevents(msg = //, &block)
+    expect(&block).to \
+      raise_error(RSpec::Mocks::MockExpectationError, msg)
+  end
+end
+
+module MatcherHelpers
+  def self.fake_matcher_description
+    "fake_matcher_description"
+  end
+
+  extend RSpec::Matchers::DSL
+
+  matcher :fake_matcher do |expected|
+    match {|actual| actual == expected}
+
+    description do
+      MatcherHelpers.fake_matcher_description
+    end
+  end
+end
+
+
+require 'rspec/support/spec'
+
+RSpec.configure do |config|
+  config.expose_dsl_globally = false
+  config.mock_with :rspec
+  config.color = true
+  config.order = :random
+
+  config.expect_with :rspec do |expectations|
+    expectations.syntax = :expect
+  end
+
+  config.mock_with :rspec do |mocks|
+    $default_rspec_mocks_syntax = mocks.syntax
+    mocks.syntax = :expect
+  end
+
+  old_verbose = nil
+  config.before(:each, :silence_warnings) do
+    old_verbose = $VERBOSE
+    $VERBOSE = nil
+  end
+
+  config.after(:each, :silence_warnings) do
+    $VERBOSE = old_verbose
+  end
+
+  config.include VerifyAndResetHelpers
+  config.include MatcherHelpers
+  config.include VerificationHelpers
+  config.extend RSpec::Support::RubyFeatures
+  config.include RSpec::Support::RubyFeatures
+
+  config.define_derived_metadata :ordered_and_vauge_counts_unsupported do |meta|
+    meta[:pending] = "`.ordered` combined with a vauge count (e.g. `at_least` or `at_most`) is not yet supported (see #713)"
+  end
+
+  # We have yet to try to address this issue, and it's just noise in our output,
+  # so skip it locally. However, on CI we want it to still run them so that if
+  # we do something that makes these specs pass, we are notified.
+  config.filter_run_excluding :ordered_and_vauge_counts_unsupported unless ENV['CI']
+
+  RSpec::Matchers.define_negated_matcher :a_string_excluding, :include
+end
+
+RSpec.shared_context "with syntax" do |syntax|
+  orig_syntax = nil
+
+  before(:all) do
+    orig_syntax = RSpec::Mocks.configuration.syntax
+    RSpec::Mocks.configuration.syntax = syntax
+  end
+
+  after(:all) do
+    RSpec::Mocks.configuration.syntax = orig_syntax
+  end
+end
+
+
+RSpec.shared_context "with isolated configuration" do
+  orig_configuration = nil
+  before do
+    orig_configuration = RSpec::Mocks.configuration
+    RSpec::Mocks.instance_variable_set(:@configuration, RSpec::Mocks::Configuration.new)
+  end
+
+  after do
+    RSpec::Mocks.instance_variable_set(:@configuration, orig_configuration)
+  end
+end
+
+RSpec.shared_context "with monkey-patched marshal" do
+  before do
+    RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = true
+  end
+
+  after do
+    RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = false
+  end
+end
+
+RSpec.shared_context "with the default mocks syntax" do
+  orig_syntax = nil
+
+  before(:all) do
+    orig_syntax = RSpec::Mocks.configuration.syntax
+    RSpec::Mocks.configuration.reset_syntaxes_to_default
+  end
+
+  after(:all) do
+    RSpec::Mocks.configuration.syntax = orig_syntax
+  end
+end
diff --git a/rspec-mocks/spec/support/before_all_shared_example_group.rb b/rspec-mocks/spec/support/before_all_shared_example_group.rb
new file mode 100644
index 0000000..ecdba06
--- /dev/null
+++ b/rspec-mocks/spec/support/before_all_shared_example_group.rb
@@ -0,0 +1,16 @@
+RSpec.shared_examples "fails in a before(:all) block" do
+  the_error = nil
+  before(:all) do
+    begin
+      use_rspec_mocks
+    rescue
+      the_error = $!
+    end
+  end
+
+  it "raises an error with a useful message" do
+    expect(the_error).to be_a_kind_of(RSpec::Mocks::OutsideOfExampleError)
+
+    expect(the_error.message).to match(/The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported./)
+  end
+end
diff --git a/rspec-mocks/spec/support/doubled_classes.rb b/rspec-mocks/spec/support/doubled_classes.rb
new file mode 100644
index 0000000..c83e9af
--- /dev/null
+++ b/rspec-mocks/spec/support/doubled_classes.rb
@@ -0,0 +1,86 @@
+class LoadedClass
+  extend RSpec::Support::RubyFeatures
+
+  M = :m
+  N = :n
+  INSTANCE = LoadedClass.new
+
+  class << self
+
+    def respond_to?(method_name, include_all = false)
+      return true if method_name == :dynamic_class_method
+      super
+    end
+
+    def defined_class_method
+    end
+
+    def send
+      # fake out!
+    end
+
+    def defined_instance_and_class_method
+    end
+
+  protected
+
+    def defined_protected_class_method
+    end
+
+  private
+
+    def defined_private_class_method
+    end
+
+  end
+
+  def defined_instance_method
+  end
+
+  def instance_method_with_two_args(a, b)
+  end
+
+  def instance_method_with_only_defaults(a=1, b=2)
+  end
+
+  def defined_instance_and_class_method
+  end
+
+  if required_kw_args_supported?
+    # Need to eval this since it is invalid syntax on earlier rubies.
+    eval <<-RUBY
+      def kw_args_method(foo, optional_arg:'hello', required_arg:)
+      end
+
+      def mixed_args_method(foo, bar, optional_arg_1:1, optional_arg_2:2)
+      end
+    RUBY
+  end
+
+  def send(*)
+  end
+
+  def respond_to?(method_name, include_all = false)
+    return true if method_name == :dynamic_instance_method
+    super
+  end
+
+  class Nested; end
+
+protected
+
+  def defined_protected_method
+  end
+
+private
+
+  def defined_private_method
+    "wink wink ;)"
+  end
+end
+
+class LoadedClassWithOverridenName < LoadedClass
+  def self.name
+    "Overriding name is not a good idea but we can't count on users not doing this"
+  end
+end
diff --git a/rspec-mocks/spec/support/matchers.rb b/rspec-mocks/spec/support/matchers.rb
new file mode 100644
index 0000000..abaacf7
--- /dev/null
+++ b/rspec-mocks/spec/support/matchers.rb
@@ -0,0 +1,15 @@
+module RSpec
+  module Matchers
+    def fail
+      raise_error(RSpec::Mocks::MockExpectationError)
+    end
+
+    def fail_with(message)
+      raise_error(RSpec::Mocks::MockExpectationError, message)
+    end
+
+    def fail_matching(message)
+      raise_error(RSpec::Mocks::MockExpectationError, (String === message ? /#{Regexp.escape(message)}/ : message))
+    end
+  end
+end
diff --git a/rspec-support/.gitignore b/rspec-support/.gitignore
new file mode 100644
index 0000000..1634377
--- /dev/null
+++ b/rspec-support/.gitignore
@@ -0,0 +1,21 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
+bin
+bundle
+
+Gemfile-custom
diff --git a/rspec-support/.rspec b/rspec-support/.rspec
new file mode 100644
index 0000000..7b10efc
--- /dev/null
+++ b/rspec-support/.rspec
@@ -0,0 +1,4 @@
+--order random
+--color
+--warnings
+-r spec_helper
diff --git a/rspec-support/.rubocop.yml b/rspec-support/.rubocop.yml
new file mode 100644
index 0000000..e2e6805
--- /dev/null
+++ b/rspec-support/.rubocop.yml
@@ -0,0 +1 @@
+inherit_from: .rubocop_rspec_base.yml
diff --git a/rspec-support/.rubocop_rspec_base.yml b/rspec-support/.rubocop_rspec_base.yml
new file mode 100644
index 0000000..f7bea1c
--- /dev/null
+++ b/rspec-support/.rubocop_rspec_base.yml
@@ -0,0 +1,130 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# This file contains defaults for RSpec projects. Individual projects
+# can customize by inheriting this file and overriding particular settings.
+
+AccessModifierIndentation:
+  EnforcedStyle: outdent
+
+# "Use alias_method instead of alias"
+# We're fine with `alias`.
+Alias:
+  Enabled: false
+
+AlignParameters:
+  EnforcedStyle: with_first_parameter
+
+# "Avoid the use of the case equality operator ==="
+# We prefer using `Class#===` over `Object#is_a?` because `Class#===`
+# is less likely to be monkey patched than `is_a?` on a user object.
+CaseEquality:
+  Enabled: false
+
+# Warns when the class is excessively long.
+ClassLength:
+  Max: 100
+
+CollectionMethods:
+  PreferredMethods:
+    reduce: 'inject'
+
+# Over time we'd like to get this down, but this is what we're at now.
+CyclomaticComplexity:
+  Max: 10
+
+# We use YARD to enforce documentation. It works better than rubocop's
+# enforcement...rubocop complains about the places we re-open
+# `RSpec::Expectations` and `RSpec::Matchers` w/o having doc commments.
+Documentation:
+  Enabled: false
+
+# We still support 1.8.7 which requires trailing dots
+DotPosition:
+  EnforcedStyle: trailing
+
+DoubleNegation:
+  Enabled: false
+
+# each_with_object is unavailable on 1.8.7 so we have to disable this one.
+EachWithObject:
+  Enabled: false
+
+Encoding:
+  EnforcedStyle: when_needed
+
+FormatString:
+  EnforcedStyle: percent
+
+# As long as we support ruby 1.8.7 we have to use hash rockets.
+HashSyntax:
+  EnforcedStyle: hash_rockets
+
+# We can't use the new lambda syntax, since we still support 1.8.7.
+Lambda:
+  Enabled: false
+
+# Over time we'd like to get this down, but this is what we're at now.
+LineLength:
+  Max: 100
+
+# Over time we'd like to get this down, but this is what we're at now.
+MethodLength:
+  Max: 15
+
+# Who cares what we call the argument for binary operator methods?
+OpMethod:
+  Enabled: false
+
+PercentLiteralDelimiters:
+  PreferredDelimiters:
+    '%':  ()      # double-quoted string
+    '%i': '[]'    # array of symbols
+    '%q': ()      # single-quoted string
+    '%Q': ()      # double-quoted string
+    '%r': '{}'    # regular expression pattern
+    '%s': ()      # a symbol
+    '%w': '[]'    # array of single-quoted strings
+    '%W': '[]'    # array of double-quoted strings
+    '%x': ()      # a shell command as a string
+
+# We have too many special cases where we allow generator methods or prefer a
+# prefixed predicate due to it's improved readability.
+PredicateName:
+  Enabled: false
+
+# On 1.8 `proc` is `lambda`, so we use `Proc.new` to ensure we get real procs on all supported versions.
+# http://batsov.com/articles/2014/02/04/the-elements-of-style-in-ruby-number-12-proc-vs-proc-dot-new/
+Proc:
+  Enabled: false
+
+RedundantReturn:
+  AllowMultipleReturnValues: true
+
+# We have to rescue Exception in the `raise_error` matcher for it to work properly.
+RescueException:
+  Enabled: false
+
+# We haven't adopted the `fail` to signal exceptions vs `raise` for re-raises convention.
+SignalException:
+  Enabled: false
+
+# We've tended to use no space, so it's less of a change to stick with that.
+SpaceAroundEqualsInParameterDefault:
+  EnforcedStyle: no_space
+
+# We don't care about single vs double qoutes.
+StringLiterals:
+  Enabled: false
+
+# This rule favors constant names from the English standard library which we don't load.
+Style/SpecialGlobalVars:
+  Enabled: false
+
+Style/TrailingComma:
+  Enabled: false
+
+TrivialAccessors:
+  AllowDSLWriters: true
+  AllowPredicates: true
+  ExactNameMatch: true
diff --git a/rspec-support/.travis.yml b/rspec-support/.travis.yml
new file mode 100644
index 0000000..ea4f1b0
--- /dev/null
+++ b/rspec-support/.travis.yml
@@ -0,0 +1,37 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+language: ruby
+sudo: false
+cache:
+  directories:
+    - ../bundle
+before_install:
+  - "script/clone_all_rspec_repos"
+  # Downgrade bundler to work around https://github.com/bundler/bundler/issues/3004
+  # Note this doesn't work on JRUBY 2.0.0 mode so we don't do it
+  - if [ -z "$JRUBY_OPTS" ]; then gem install bundler -v=1.5.3 && alias bundle="bundle _1.5.3_"; fi
+bundler_args: "--binstubs --standalone --without documentation --path ../bundle"
+script: "script/run_build"
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - 2.1
+  - 2.2
+  - ruby-head
+  - ree
+  - jruby-18mode
+  - jruby
+  - jruby-head
+  - rbx
+matrix:
+  include:
+    - rvm: jruby
+      env: JRUBY_OPTS='--2.0'
+  allow_failures:
+    - rvm: jruby-head
+    - rvm: ruby-head
+    - rvm: rbx
+  fast_finish: true
diff --git a/rspec-support/Changelog.md b/rspec-support/Changelog.md
new file mode 100644
index 0000000..56cf6c9
--- /dev/null
+++ b/rspec-support/Changelog.md
@@ -0,0 +1,105 @@
+### 3.2.2 / 2015-02-23
+
+Bug Fixes:
+
+* Fix an encoding issue with `EncodedString#split` when encountering an
+  invalid byte string. (Benjamin Fleischer, #1760)
+
+### 3.2.1 / 2015-02-04
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.0...v3.2.1)
+
+Bug Fixes:
+
+* Fix `RSpec::CallerFilter` to work on Rubinius 2.2.
+  (Myron Marston, #169)
+
+### 3.2.0 / 2015-02-03
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.2...v3.2.0)
+
+Enhancements:
+
+* Add extra Ruby type detection. (Jon Rowe, #133)
+* Make differ instance re-usable. (Alexey Fedorov, #160)
+
+Bug Fixes:
+
+* Do not consider `[]` and `{}` to match when performing fuzzy matching.
+  (Myron Marston, #157)
+
+### 3.1.2 / 2014-10-08
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.1...v3.1.2)
+
+Bug Fixes:
+
+* Fix method signature to not blow up with a `NoMethodError` on 1.8.7 when
+  verifying against an RSpec matcher. (Myron Marston, #116)
+
+### 3.1.1 / 2014-09-26
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.0...v3.1.1)
+
+Bug Fixes:
+
+* Fix `RSpec::Support::DirectoryMaker` (used by `rspec --init` and
+  `rails generate rspec:install`) so that it detects absolute paths
+   on Windows properly. (Scott Archer, #107, #108, #109) (Jon Rowe, #110)
+
+### 3.1.0 / 2014-09-04
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.4...v3.1.0)
+
+Bug Fixes:
+
+* Fix `FuzzyMatcher` so that it does not wrongly match a struct against
+  an array. (Myron Marston, #97)
+* Prevent infinitely recursing `#flatten` methods from causing the differ
+  to hang. (Jon Rowe, #101)
+
+### 3.0.4 / 2014-08-14
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.3...v3.0.4)
+
+Bug Fixes:
+
+* Fix `FuzzyMatcher` so that it does not silence `ArgumentError` raised
+  from broken implementations of `==`. (Myron Marston, #94)
+
+### 3.0.3 / 2014-07-21
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.2...v3.0.3)
+
+Bug Fixes:
+
+* Fix regression in `Support#method_handle_for` where proxy objects
+  with method delegated would wrongly not return a method handle.
+  (Jon Rowe, #90)
+* Properly detect Module#prepend support in Ruby 2.1+ (Ben Langfeld, #91)
+* Fix `rspec/support/warnings.rb` so it can be loaded and used in
+  isolation. (Myron Marston, #93)
+
+### 3.0.2 / 2014-06-20
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.1...v3.0.2)
+
+* Revert `BlockSignature` change from 3.0.1 because of a ruby bug that
+  caused it to change the block's behavior (https://bugs.ruby-lang.org/issues/9967).
+  (Myron Marston, rspec-mocks#721)
+
+### 3.0.1 / 2014-06-19
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0...v3.0.1)
+
+* Fix `BlockSignature` so that it correctly differentiates between
+  required and optional block args. (Myron Marston, rspec-mocks#714)
+
+### 3.0.0 / 2014-06-01
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.rc1...v3.0.0)
+
+### 3.0.0.rc1 / 2014-05-18
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta2...v3.0.0.rc1)
+
+### 3.0.0.beta2 / 2014-02-17
+[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta1...v3.0.0.beta2)
+
+Bug Fixes:
+
+* Issue message when :replacement is passed to `RSpec.warn_with`. (Jon Rowe)
+
+### 3.0.0.beta1 / 2013-11-07
+[Full Changelog](https://github.com/rspec/rspec-support/compare/0dc12d1bdbbacc757a9989f8c09cd08ef3a4837e...v3.0.0.beta1)
+
+Initial release.
diff --git a/rspec-support/Gemfile b/rspec-support/Gemfile
new file mode 100644
index 0000000..4cae93c
--- /dev/null
+++ b/rspec-support/Gemfile
@@ -0,0 +1,21 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in rspec-support.gemspec
+gemspec
+
+branch = File.read(File.expand_path("../maintenance-branch", __FILE__)).chomp
+%w[rspec rspec-core rspec-expectations rspec-mocks].each do |lib|
+  library_path = File.expand_path("../../#{lib}", __FILE__)
+  if File.exist?(library_path) && !ENV['USE_GIT_REPOS']
+    gem lib, :path => library_path
+  else
+    gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => branch
+  end
+end
+
+### dep for ci/coverage
+gem 'simplecov', '~> 0.8'
+
+gem 'rubocop', "~> 0.23.0", :platform => [:ruby_19, :ruby_20, :ruby_21]
+
+eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
diff --git a/License.txt b/rspec-support/LICENSE.txt
similarity index 58%
copy from License.txt
copy to rspec-support/LICENSE.txt
index 02bc06c..ecb71df 100644
--- a/License.txt
+++ b/rspec-support/LICENSE.txt
@@ -1,8 +1,6 @@
-(The MIT License)
+Copyright (c) 2013 David Chelimsky, Myron Marston, Jon Rowe, Sam Phippen, Xavier Shay, Bradley Schaefer
 
-Copyright (c) 2009 Chad Humphries, David Chelimsky
-Copyright (c) 2006 David Chelimsky, The RSpec Development Team
-Copyright (c) 2005 Steven Baker
+MIT License
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -17,8 +15,8 @@ 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.
+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.
diff --git a/rspec-support/README.md b/rspec-support/README.md
new file mode 100644
index 0000000..7c433a2
--- /dev/null
+++ b/rspec-support/README.md
@@ -0,0 +1,26 @@
+# RSpec::Support
+
+`RSpec::Support` provides common functionality to `RSpec::Core`,
+`RSpec::Expectations` and `RSpec::Mocks`. It is considered
+suitable for internal use only at this time.
+
+## Installation / Usage
+
+Install one or more of the `RSpec` gems.
+
+Want to run against the `master` branch? You'll need to include the dependent
+RSpec repos as well. Add the following to your `Gemfile`:
+
+```ruby
+%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
+  gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => 'master'
+end
+```
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
diff --git a/rspec-support/Rakefile b/rspec-support/Rakefile
new file mode 100644
index 0000000..6756730
--- /dev/null
+++ b/rspec-support/Rakefile
@@ -0,0 +1,30 @@
+require "bundler"
+Bundler.setup
+Bundler::GemHelper.install_tasks
+
+require "rake"
+
+require "rspec/core/rake_task"
+require "rspec/core/version"
+
+desc "Run all examples"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.ruby_opts = %w[-w]
+end
+
+task :default => [:spec]
+
+task :verify_private_key_present do
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  unless File.exist?(private_key)
+    raise "Your private key is not present. This gem should not be built without that."
+  end
+end
+
+task :build => :verify_private_key_present
+
+require 'rubocop/rake_task'
+desc 'Run RuboCop on the lib directory'
+RuboCop::RakeTask.new(:rubocop) do |task|
+  task.patterns = ['lib/**/*.rb']
+end
diff --git a/rspec-support/appveyor.yml b/rspec-support/appveyor.yml
new file mode 100644
index 0000000..9e4f457
--- /dev/null
+++ b/rspec-support/appveyor.yml
@@ -0,0 +1,34 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+version: "{build}"
+
+# This will build all PRs targetting matching branches.
+# Without this, each PR builds twice -- once for the PR branch HEAD,
+# and once for the merge commit that github creates for each mergable PR.
+branches:
+  only:
+    - master
+    - /.*-maintenance$/
+
+# Disable normal Windows builds in favor of our test script.
+build: off
+
+install:
+  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
+  - ruby --version
+  - gem --version
+  # We lock to 1.7.7 to avoid warnings from 1.7.8
+  - gem install bundler -v=1.7.7
+  - bundler --version
+  - bundle install
+  - cinst ansicon
+
+test_script:
+  - bundle exec rspec
+
+environment:
+  matrix:
+    # ruby_version: '20' doesn't work for some reason
+    - ruby_version: '193'
+    - ruby_version: '21'
diff --git a/rspec-support/benchmarks/caller.rb b/rspec-support/benchmarks/caller.rb
new file mode 100644
index 0000000..6d160c8
--- /dev/null
+++ b/rspec-support/benchmarks/caller.rb
@@ -0,0 +1,81 @@
+$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
+
+require 'benchmark'
+require 'rspec/support/caller_filter'
+
+n = 10000
+
+puts "#{n} times - ruby #{RUBY_VERSION}"
+puts
+
+puts "* Using a chunked fetch is quicker than the old method of array-access."
+Benchmark.bm(20) do |bm|
+  bm.report("CallerFilter") do
+    n.times do
+      RSpec::CallerFilter.first_non_rspec_line
+    end
+  end
+
+  bm.report("Direct caller access") do
+    n.times do
+      caller(1)[4]
+    end
+  end
+end
+
+puts
+puts "* Chunking fetches of caller adds a ~17% overhead."
+Benchmark.bm(20) do |bm|
+  bm.report("Chunked") do
+    n.times do
+      caller(1, 2)
+      caller(3, 2)
+      caller(5, 2)
+    end
+  end
+
+  bm.report("All at once") do
+    n.times do
+      caller(1, 6)
+    end
+  end
+end
+
+puts
+puts "* `caller` scales linearly with length parameter."
+Benchmark.bm(20) do |bm|
+  (1..10).each do |x|
+    bm.report(x) do
+      n.times do
+        caller(1, x)
+      end
+    end
+  end
+end
+
+
+# > ruby benchmarks/caller.rb
+# 10000 times - ruby 2.0.0
+#
+# * Using a chunked fetch is quicker than the old method of array-access.
+#                            user     system      total        real
+# CallerFilter            0.140000   0.010000   0.150000 (  0.145381)
+# Direct caller access   0.170000   0.000000   0.170000 (  0.180610)
+#
+# * Chunking fetches of caller adds a ~17% overhead.
+#                            user     system      total        real
+# Chunked                0.150000   0.000000   0.150000 (  0.181162)
+# All at once            0.130000   0.010000   0.140000 (  0.138732)
+#
+# * `caller` scales linearly with length parameter.
+#                            user     system      total        real
+# 1                      0.030000   0.000000   0.030000 (  0.035000)
+# 2                      0.050000   0.000000   0.050000 (  0.059879)
+# 3                      0.080000   0.000000   0.080000 (  0.098468)
+# 4                      0.090000   0.010000   0.100000 (  0.097619)
+# 5                      0.110000   0.000000   0.110000 (  0.126220)
+# 6                      0.130000   0.000000   0.130000 (  0.136739)
+# 7                      0.150000   0.000000   0.150000 (  0.159055)
+# 8                      0.160000   0.010000   0.170000 (  0.172416)
+# 9                      0.180000   0.000000   0.180000 (  0.203038)
+# 10                     0.200000   0.000000   0.200000 (  0.210551)
diff --git a/rspec-support/benchmarks/caller_vs_caller_locations.rb b/rspec-support/benchmarks/caller_vs_caller_locations.rb
new file mode 100644
index 0000000..df1ad06
--- /dev/null
+++ b/rspec-support/benchmarks/caller_vs_caller_locations.rb
@@ -0,0 +1,19 @@
+require 'benchmark/ips'
+
+Benchmark.ips do |x|
+  x.report("caller()              ") { caller }
+  x.report("caller_locations()    ") { caller_locations }
+  x.report("caller(1, 2)          ") { caller(1, 2) }
+  x.report("caller_locations(1, 2)") { caller_locations(1, 2) }
+end
+
+__END__
+
+caller()
+                        118.586k (±17.7%) i/s -    573.893k
+caller_locations()
+                        355.988k (±17.8%) i/s -      1.709M
+caller(1, 2)
+                        336.841k (±18.6%) i/s -      1.615M
+caller_locations(1, 2)
+                        781.330k (±23.5%) i/s -      3.665M
diff --git a/rspec-support/benchmarks/skip_frames_for_caller_filter.rb b/rspec-support/benchmarks/skip_frames_for_caller_filter.rb
new file mode 100644
index 0000000..822211a
--- /dev/null
+++ b/rspec-support/benchmarks/skip_frames_for_caller_filter.rb
@@ -0,0 +1,27 @@
+require 'rspec/support/caller_filter'
+
+eval <<-EOS, binding, "/lib/rspec/core/some_file.rb", 1 # make it think this code is in rspec-core
+  class Recurser
+    def self.recurse(times, *args)
+      return RSpec::CallerFilter.first_non_rspec_line(*args) if times.zero?
+      recurse(times - 1, *args)
+    end
+  end
+EOS
+
+# Ensure the correct first_non_rspec_line is found in these cases.
+puts Recurser.recurse(20, 19)
+puts Recurser.recurse(20)
+
+require 'benchmark/ips'
+
+Benchmark.ips do |x|
+  x.report("(no args)") { Recurser.recurse(20)        }
+  x.report("(19)")      { Recurser.recurse(20, 19)    }
+  x.report("(19, 2)")   { Recurser.recurse(20, 19, 2) }
+end
+
+__END__
+ (no args)     13.789k (± 7.8%) i/s -     69.377k
+      (19)     55.410k (± 8.4%) i/s -    275.123k
+   (19, 2)     61.076k (± 8.6%) i/s -    303.637k
diff --git a/rspec-support/lib/rspec/support.rb b/rspec-support/lib/rspec/support.rb
new file mode 100644
index 0000000..d45ff84
--- /dev/null
+++ b/rspec-support/lib/rspec/support.rb
@@ -0,0 +1,76 @@
+module RSpec
+  module Support
+    # @api private
+    #
+    # Defines a helper method that is optimized to require files from the
+    # named lib. The passed block MUST be `{ |f| require_relative f }`
+    # because for `require_relative` to work properly from within the named
+    # lib the line of code must be IN that lib.
+    #
+    # `require_relative` is preferred when available because it is always O(1),
+    # regardless of the number of dirs in $LOAD_PATH. `require`, on the other
+    # hand, does a linear O(N) search over the dirs in the $LOAD_PATH until
+    # it can resolve the file relative to one of the dirs.
+    def self.define_optimized_require_for_rspec(lib, &require_relative)
+      name = "require_rspec_#{lib}"
+
+      if Kernel.respond_to?(:require_relative)
+        (class << self; self; end).__send__(:define_method, name) do |f|
+          require_relative.call("#{lib}/#{f}")
+        end
+      else
+        (class << self; self; end).__send__(:define_method, name) do |f|
+          require "rspec/#{lib}/#{f}"
+        end
+      end
+    end
+
+    define_optimized_require_for_rspec(:support) { |f| require_relative(f) }
+    require_rspec_support "version"
+    require_rspec_support "ruby_features"
+
+    # @api private
+    KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method)
+
+    # @api private
+    #
+    # Used internally to get a method handle for a particular object
+    # and method name.
+    #
+    # Includes handling for a few special cases:
+    #
+    #   - Objects that redefine #method (e.g. an HTTPRequest struct)
+    #   - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator)
+    #   - Objects that undefine method and delegate everything to another
+    #     object (e.g. Mongoid association objects)
+    if RubyFeatures.supports_rebinding_module_methods?
+      def self.method_handle_for(object, method_name)
+        KERNEL_METHOD_METHOD.bind(object).call(method_name)
+      rescue NameError => original
+        begin
+          handle = object.method(method_name)
+          raise original unless handle.is_a? Method
+          handle
+        rescue Exception
+          raise original
+        end
+      end
+    else
+      def self.method_handle_for(object, method_name)
+        if ::Kernel === object
+          KERNEL_METHOD_METHOD.bind(object).call(method_name)
+        else
+          object.method(method_name)
+        end
+      rescue NameError => original
+        begin
+          handle = object.method(method_name)
+          raise original unless handle.is_a? Method
+          handle
+        rescue Exception
+          raise original
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/caller_filter.rb b/rspec-support/lib/rspec/support/caller_filter.rb
new file mode 100644
index 0000000..eb6f4dc
--- /dev/null
+++ b/rspec-support/lib/rspec/support/caller_filter.rb
@@ -0,0 +1,83 @@
+RSpec::Support.require_rspec_support "ruby_features"
+
+module RSpec
+  # Consistent implementation for "cleaning" the caller method to strip out
+  # non-rspec lines. This enables errors to be reported at the call site in
+  # the code using the library, which is far more useful than the particular
+  # internal method that raised an error.
+  class CallerFilter
+    RSPEC_LIBS = %w[
+      core
+      mocks
+      expectations
+      support
+      matchers
+      rails
+    ]
+
+    ADDITIONAL_TOP_LEVEL_FILES = %w[ autorun ]
+
+    LIB_REGEX = %r{/lib/rspec/(#{(RSPEC_LIBS + ADDITIONAL_TOP_LEVEL_FILES).join('|')})(\.rb|/)}
+
+    # rubygems/core_ext/kernel_require.rb isn't actually part of rspec (obviously) but we want
+    # it ignored when we are looking for the first meaningful line of the backtrace outside
+    # of RSpec. It can show up in the backtrace as the immediate first caller
+    # when `CallerFilter.first_non_rspec_line` is called from the top level of a required
+    # file, but it depends on if rubygems is loaded or not. We don't want to have to deal
+    # with this complexity in our `RSpec.deprecate` calls, so we ignore it here.
+    IGNORE_REGEX = Regexp.union(LIB_REGEX, "rubygems/core_ext/kernel_require.rb")
+
+    if RSpec::Support::RubyFeatures.caller_locations_supported?
+      # This supports args because it's more efficient when the caller specifies
+      # these. It allows us to skip frames the caller knows are part of RSpec,
+      # and to decrease the increment size if the caller is confident the line will
+      # be found in a small number of stack frames from `skip_frames`.
+      #
+      # Note that there is a risk to passing a `skip_frames` value that is too high:
+      # If it skippped the first non-rspec line, then this method would return the
+      # 2nd or 3rd (or whatever) non-rspec line. Thus, you generally shouldn't pass
+      # values for these parameters, particularly since most places that use this are
+      # not hot spots (generally it gets used for deprecation warnings). However,
+      # if you do have a hot spot that calls this, passing `skip_frames` can make
+      # a significant difference. Just make sure that that particular use is tested
+      # so that if the provided `skip_frames` changes to no longer be accurate in
+      # such a way that would return the wrong stack frame, a test will fail to tell you.
+      #
+      # See benchmarks/skip_frames_for_caller_filter.rb for measurements.
+      def self.first_non_rspec_line(skip_frames=3, increment=5)
+        # Why a default `skip_frames` of 3?
+        # By the time `caller_locations` is called below, the first 3 frames are:
+        #   lib/rspec/support/caller_filter.rb:63:in `block in first_non_rspec_line'
+        #   lib/rspec/support/caller_filter.rb:62:in `loop'
+        #   lib/rspec/support/caller_filter.rb:62:in `first_non_rspec_line'
+
+        # `caller` is an expensive method that scales linearly with the size of
+        # the stack. The performance hit for fetching it in chunks is small,
+        # and since the target line is probably near the top of the stack, the
+        # overall improvement of a chunked search like this is significant.
+        #
+        # See benchmarks/caller.rb for measurements.
+
+        # The default increment of 5 for this method are mostly arbitrary, but
+        # is chosen to give good performance on the common case of creating a double.
+
+        loop do
+          stack = caller_locations(skip_frames, increment)
+          raise "No non-lib lines in stack" unless stack
+
+          line = stack.find { |l| l.path !~ IGNORE_REGEX }
+          return line.to_s if line
+
+          skip_frames += increment
+          increment   *= 2 # The choice of two here is arbitrary.
+        end
+      end
+    else
+      # Earlier rubies do not support the two argument form of `caller`. This
+      # fallback is logically the same, but slower.
+      def self.first_non_rspec_line(*)
+        caller.find { |line| line !~ IGNORE_REGEX }
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/differ.rb b/rspec-support/lib/rspec/support/differ.rb
new file mode 100644
index 0000000..2d5c34f
--- /dev/null
+++ b/rspec-support/lib/rspec/support/differ.rb
@@ -0,0 +1,215 @@
+RSpec::Support.require_rspec_support 'encoded_string'
+RSpec::Support.require_rspec_support 'hunk_generator'
+
+require 'pp'
+
+module RSpec
+  module Support
+    # rubocop:disable ClassLength
+    class Differ
+      def diff(actual, expected)
+        diff = ""
+
+        if actual && expected
+          if all_strings?(actual, expected)
+            if any_multiline_strings?(actual, expected)
+              diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected))
+            end
+          elsif no_procs?(actual, expected) && no_numbers?(actual, expected)
+            diff = diff_as_object(actual, expected)
+          end
+        end
+
+        diff.to_s
+      end
+
+      # rubocop:disable MethodLength
+      def diff_as_string(actual, expected)
+        encoding = pick_encoding(actual, expected)
+
+        actual   = EncodedString.new(actual, encoding)
+        expected = EncodedString.new(expected, encoding)
+
+        output = EncodedString.new("\n", encoding)
+        hunks = build_hunks(actual, expected)
+
+        hunks.each_cons(2) do |prev_hunk, current_hunk|
+          begin
+            if current_hunk.overlaps?(prev_hunk)
+              add_old_hunk_to_hunk(current_hunk, prev_hunk)
+            else
+              add_to_output(output, prev_hunk.diff(format_type).to_s)
+            end
+          ensure
+            add_to_output(output, "\n")
+          end
+        end
+
+        finalize_output(output, hunks.last.diff(format_type).to_s) if hunks.last
+
+        color_diff output
+      rescue Encoding::CompatibilityError
+        handle_encoding_errors(actual, expected)
+      end
+      # rubocop:enable MethodLength
+
+      def diff_as_object(actual, expected)
+        actual_as_string = object_to_string(actual)
+        expected_as_string = object_to_string(expected)
+        diff_as_string(actual_as_string, expected_as_string)
+      end
+
+      attr_reader :color
+      alias_method :color?, :color
+
+      def initialize(opts={})
+        @color = opts.fetch(:color, false)
+        @object_preparer = opts.fetch(:object_preparer, lambda { |string| string })
+      end
+
+    private
+
+      def no_procs?(*args)
+        safely_flatten(args).none? { |a| Proc === a }
+      end
+
+      def all_strings?(*args)
+        safely_flatten(args).all? { |a| String === a }
+      end
+
+      def any_multiline_strings?(*args)
+        all_strings?(*args) && safely_flatten(args).any? { |a| multiline?(a) }
+      end
+
+      def no_numbers?(*args)
+        safely_flatten(args).none? { |a| Numeric === a }
+      end
+
+      def coerce_to_string(string_or_array)
+        return string_or_array unless Array === string_or_array
+        diffably_stringify(string_or_array).join("\n")
+      end
+
+      def diffably_stringify(array)
+        array.map do |entry|
+          if Array === entry
+            entry.inspect
+          else
+            entry.to_s.gsub("\n", "\\n")
+          end
+        end
+      end
+
+      if String.method_defined?(:encoding)
+        def multiline?(string)
+          string.include?("\n".encode(string.encoding))
+        end
+      else
+        def multiline?(string)
+          string.include?("\n")
+        end
+      end
+
+      def build_hunks(actual, expected)
+        HunkGenerator.new(actual, expected).hunks
+      end
+
+      def finalize_output(output, final_line)
+        add_to_output(output, final_line)
+        add_to_output(output, "\n")
+      end
+
+      def add_to_output(output, string)
+        output << string
+      end
+
+      def add_old_hunk_to_hunk(hunk, oldhunk)
+        hunk.merge(oldhunk)
+      end
+
+      def safely_flatten(array)
+        array = array.flatten(1) until (array == array.flatten(1))
+        array
+      end
+
+      def format_type
+        :unified
+      end
+
+      def color(text, color_code)
+        "\e[#{color_code}m#{text}\e[0m"
+      end
+
+      def red(text)
+        color(text, 31)
+      end
+
+      def green(text)
+        color(text, 32)
+      end
+
+      def blue(text)
+        color(text, 34)
+      end
+
+      def normal(text)
+        color(text, 0)
+      end
+
+      def color_diff(diff)
+        return diff unless color?
+
+        diff.lines.map do |line|
+          case line[0].chr
+          when "+"
+            green line
+          when "-"
+            red line
+          when "@"
+            line[1].chr == "@" ? blue(line) : normal(line)
+          else
+            normal(line)
+          end
+        end.join
+      end
+
+      def object_to_string(object)
+        object = @object_preparer.call(object)
+        case object
+        when Hash
+          object.keys.sort_by { |k| k.to_s }.map do |key|
+            pp_key   = PP.singleline_pp(key, "")
+            pp_value = PP.singleline_pp(object[key], "")
+
+            "#{pp_key} => #{pp_value},"
+          end.join("\n")
+        when String
+          object =~ /\n/ ? object : object.inspect
+        else
+          PP.pp(object, "")
+        end
+      end
+
+      if String.method_defined?(:encoding)
+        def pick_encoding(source_a, source_b)
+          Encoding.compatible?(source_a, source_b) || Encoding.default_external
+        end
+      else
+        def pick_encoding(_source_a, _source_b)
+        end
+      end
+
+      def handle_encoding_errors(actual, expected)
+        if actual.source_encoding != expected.source_encoding
+          "Could not produce a diff because the encoding of the actual string " \
+          "(#{actual.source_encoding}) differs from the encoding of the expected " \
+          "string (#{expected.source_encoding})"
+        else
+          "Could not produce a diff because of the encoding of the string " \
+          "(#{expected.source_encoding})"
+        end
+      end
+    end
+    # rubocop:enable ClassLength
+  end
+end
diff --git a/rspec-support/lib/rspec/support/directory_maker.rb b/rspec-support/lib/rspec/support/directory_maker.rb
new file mode 100644
index 0000000..4868a81
--- /dev/null
+++ b/rspec-support/lib/rspec/support/directory_maker.rb
@@ -0,0 +1,61 @@
+RSpec::Support.require_rspec_support 'ruby_features'
+
+module RSpec
+  module Support
+    # @api private
+    #
+    # Replacement for fileutils#mkdir_p because we don't want to require parts
+    # of stdlib in RSpec.
+    class DirectoryMaker
+      # @api private
+      #
+      # Implements nested directory construction
+      def self.mkdir_p(path)
+        stack = generate_stack(path)
+        path.split(File::SEPARATOR).each do |part|
+          stack = generate_path(stack, part)
+          begin
+            Dir.mkdir(stack) unless directory_exists?(stack)
+          rescue Errno::ENOTDIR => e
+            raise Errno::EEXIST, e.message
+          end
+        end
+      end
+
+      if OS.windows_file_path?
+        def self.generate_stack(path)
+          if path.start_with?(File::SEPARATOR)
+            File::SEPARATOR
+          elsif path[1] == ':'
+            ''
+          else
+            '.'
+          end
+        end
+        def self.generate_path(stack, part)
+          if stack == ''
+            part
+          elsif stack == File::SEPARATOR
+            File.join('', part)
+          else
+            File.join(stack, part)
+          end
+        end
+      else
+        def self.generate_stack(path)
+          path.start_with?(File::SEPARATOR) ? File::SEPARATOR : "."
+        end
+        def self.generate_path(stack, part)
+          File.join(stack, part)
+        end
+      end
+
+      def self.directory_exists?(dirname)
+        File.exist?(dirname) && File.directory?(dirname)
+      end
+      private_class_method :directory_exists?
+      private_class_method :generate_stack
+      private_class_method :generate_path
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/encoded_string.rb b/rspec-support/lib/rspec/support/encoded_string.rb
new file mode 100644
index 0000000..6e14793
--- /dev/null
+++ b/rspec-support/lib/rspec/support/encoded_string.rb
@@ -0,0 +1,148 @@
+module RSpec
+  module Support
+    # @private
+    class EncodedString
+      # Reduce allocations by storing constants.
+      UTF_8    = "UTF-8"
+      US_ASCII = "US-ASCII"
+      #
+      # In MRI 2.1 'invalid: :replace' changed to also replace an invalid byte sequence
+      # see https://github.com/ruby/ruby/blob/v2_1_0/NEWS#L176
+      # https://www.ruby-forum.com/topic/6861247
+      # https://twitter.com/nalsh/status/553413844685438976
+      #
+      # For example, given:
+      #   "\x80".force_encoding("Emacs-Mule").encode(:invalid => :replace).bytes.to_a
+      #
+      # On MRI 2.1 or above: 63  # '?'
+      # else               : 128 # "\x80"
+      #
+      # Ruby's default replacement string is:
+      #   U+FFFD ("\xEF\xBF\xBD"), for Unicode encoding forms, else
+      #   ?      ("\x3F")
+      REPLACE = "?"
+      ENCODE_UNCONVERTABLE_BYTES =  {
+        :invalid => :replace,
+        :undef   => :replace,
+        :replace => REPLACE
+      }
+      ENCODE_NO_CONVERTER = {
+        :invalid => :replace,
+        :replace => REPLACE
+      }
+
+      def initialize(string, encoding=nil)
+        @encoding = encoding
+        @source_encoding = detect_source_encoding(string)
+        @string = matching_encoding(string)
+      end
+      attr_reader :source_encoding
+
+      delegated_methods = String.instance_methods.map(&:to_s) & %w[eql? lines == encoding empty?]
+      delegated_methods.each do |name|
+        define_method(name) { |*args, &block| @string.__send__(name, *args, &block) }
+      end
+
+      def <<(string)
+        @string << matching_encoding(string)
+      end
+
+      def split(regex_or_string)
+        @string.split(matching_encoding(regex_or_string))
+      end
+
+      def to_s
+        @string
+      end
+      alias :to_str :to_s
+
+      if String.method_defined?(:encoding)
+
+        private
+
+        # Encoding Exceptions:
+        #
+        # Raised by Encoding and String methods:
+        #   Encoding::UndefinedConversionError:
+        #     when a transcoding operation fails
+        #     if the String contains characters invalid for the target encoding
+        #     e.g. "\x80".encode('UTF-8','ASCII-8BIT')
+        #     vs "\x80".encode('UTF-8','ASCII-8BIT', undef: :replace, replace: '<undef>')
+        #     # => '<undef>'
+        #   Encoding::CompatibilityError
+        #     when Encoding.compatibile?(str1, str2) is nil
+        #     e.g. utf_16le_emoji_string.split("\n")
+        #     e.g. valid_unicode_string.encode(utf8_encoding) << ascii_string
+        #   Encoding::InvalidByteSequenceError:
+        #     when the string being transcoded contains a byte invalid for
+        #     either the source or target encoding
+        #     e.g. "\x80".encode('UTF-8','US-ASCII')
+        #     vs "\x80".encode('UTF-8','US-ASCII', invalid: :replace, replace: '<byte>')
+        #     # => '<byte>'
+        #   ArgumentError
+        #     when operating on a string with invalid bytes
+        #     e.g."\x80".split("\n")
+        #   TypeError
+        #     when a symbol is passed as an encoding
+        #     Encoding.find(:"UTF-8")
+        #     when calling force_encoding on an object
+        #     that doesn't respond to #to_str
+        #
+        # Raised by transcoding methods:
+        #   Encoding::ConverterNotFoundError:
+        #     when a named encoding does not correspond with a known converter
+        #     e.g. 'abc'.force_encoding('UTF-8').encode('foo')
+        #     or a converter path cannot be found
+        #     e.g. "\x80".force_encoding('ASCII-8BIT').encode('Emacs-Mule')
+        #
+        # Raised by byte <-> char conversions
+        #   RangeError: out of char range
+        #     e.g. the UTF-16LE emoji: 128169.chr
+        def matching_encoding(string)
+          string = remove_invalid_bytes(string)
+          string.encode(@encoding)
+        rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
+          string.encode(@encoding, ENCODE_UNCONVERTABLE_BYTES)
+        rescue Encoding::ConverterNotFoundError
+          string.dup.force_encoding(@encoding).encode(ENCODE_NO_CONVERTER)
+        end
+
+        # Prevents raising ArgumentError
+        if String.method_defined?(:scrub)
+          # https://github.com/ruby/ruby/blob/eeb05e8c11/doc/NEWS-2.1.0#L120-L123
+          # https://github.com/ruby/ruby/blob/v2_1_0/string.c#L8242
+          # https://github.com/hsbt/string-scrub
+          # https://github.com/rubinius/rubinius/blob/v2.5.2/kernel/common/string.rb#L1913-L1972
+          def remove_invalid_bytes(string)
+            string.scrub(REPLACE)
+          end
+        else
+          # http://stackoverflow.com/a/8711118/879854
+          # Loop over chars in a string replacing chars
+          # with invalid encoding, which is a pretty good proxy
+          # for the invalid byte sequence that causes an ArgumentError
+          def remove_invalid_bytes(string)
+            string.chars.map do |char|
+              char.valid_encoding? ? char : REPLACE
+            end.join
+          end
+        end
+
+        def detect_source_encoding(string)
+          string.encoding
+        end
+      else
+
+        private
+
+        def matching_encoding(string)
+          string
+        end
+
+        def detect_source_encoding(_string)
+          US_ASCII
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/fuzzy_matcher.rb b/rspec-support/lib/rspec/support/fuzzy_matcher.rb
new file mode 100644
index 0000000..87d6747
--- /dev/null
+++ b/rspec-support/lib/rspec/support/fuzzy_matcher.rb
@@ -0,0 +1,48 @@
+module RSpec
+  module Support
+    # Provides a means to fuzzy-match between two arbitrary objects.
+    # Understands array/hash nesting. Uses `===` or `==` to
+    # perform the matching.
+    module FuzzyMatcher
+      # @api private
+      def self.values_match?(expected, actual)
+        if Hash === actual
+          return hashes_match?(expected, actual) if Hash === expected
+        elsif Array === expected && Enumerable === actual && !(Struct === actual)
+          return arrays_match?(expected, actual.to_a)
+        end
+
+        return true if actual == expected
+
+        begin
+          expected === actual
+        rescue ArgumentError
+          # Some objects, like 0-arg lambdas on 1.9+, raise
+          # ArgumentError for `expected === actual`.
+          false
+        end
+      end
+
+      # @private
+      def self.arrays_match?(expected_list, actual_list)
+        return false if expected_list.size != actual_list.size
+
+        expected_list.zip(actual_list).all? do |expected, actual|
+          values_match?(expected, actual)
+        end
+      end
+
+      # @private
+      def self.hashes_match?(expected_hash, actual_hash)
+        return false if expected_hash.size != actual_hash.size
+
+        expected_hash.all? do |expected_key, expected_value|
+          actual_value = actual_hash.fetch(expected_key) { return false }
+          values_match?(expected_value, actual_value)
+        end
+      end
+
+      private_class_method :arrays_match?, :hashes_match?
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/hunk_generator.rb b/rspec-support/lib/rspec/support/hunk_generator.rb
new file mode 100644
index 0000000..382579e
--- /dev/null
+++ b/rspec-support/lib/rspec/support/hunk_generator.rb
@@ -0,0 +1,47 @@
+require 'diff/lcs'
+require 'diff/lcs/hunk'
+
+module RSpec
+  module Support
+    # @private
+    class HunkGenerator
+      def initialize(actual, expected)
+        @actual = actual
+        @expected = expected
+      end
+
+      def hunks
+        @file_length_difference = 0
+        @hunks ||= diffs.map do |piece|
+          build_hunk(piece)
+        end
+      end
+
+    private
+
+      def diffs
+        Diff::LCS.diff(expected_lines, actual_lines)
+      end
+
+      def expected_lines
+        @expected.split("\n").map! { |e| e.chomp }
+      end
+
+      def actual_lines
+        @actual.split("\n").map! { |e| e.chomp }
+      end
+
+      def build_hunk(piece)
+        Diff::LCS::Hunk.new(
+          expected_lines, actual_lines, piece, context_lines, @file_length_difference
+        ).tap do |h|
+          @file_length_difference = h.file_length_difference
+        end
+      end
+
+      def context_lines
+        3
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/matcher_definition.rb b/rspec-support/lib/rspec/support/matcher_definition.rb
new file mode 100644
index 0000000..d653cc1
--- /dev/null
+++ b/rspec-support/lib/rspec/support/matcher_definition.rb
@@ -0,0 +1,42 @@
+module RSpec
+  module Support
+    # @private
+    def self.matcher_definitions
+      @matcher_definitions ||= []
+    end
+
+    # Used internally to break cyclic dependency between mocks, expectations,
+    # and support. We don't currently have a consistent implementation of our
+    # matchers, though we are considering changing that:
+    # https://github.com/rspec/rspec-mocks/issues/513
+    #
+    # @private
+    def self.register_matcher_definition(&block)
+      matcher_definitions << block
+    end
+
+    # Remove a previously registered matcher. Useful for cleaning up after
+    # yourself in specs.
+    #
+    # @private
+    def self.deregister_matcher_definition(&block)
+      matcher_definitions.delete(block)
+    end
+
+    # @private
+    def self.is_a_matcher?(object)
+      matcher_definitions.any? { |md| md.call(object) }
+    end
+
+    # @api private
+    #
+    # gives a string representation of an object for use in RSpec descriptions
+    def self.rspec_description_for_object(object)
+      if RSpec::Support.is_a_matcher?(object) && object.respond_to?(:description)
+        object.description
+      else
+        object
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/method_signature_verifier.rb b/rspec-support/lib/rspec/support/method_signature_verifier.rb
new file mode 100644
index 0000000..0ab85ca
--- /dev/null
+++ b/rspec-support/lib/rspec/support/method_signature_verifier.rb
@@ -0,0 +1,273 @@
+require 'rspec/support'
+RSpec::Support.require_rspec_support "ruby_features"
+RSpec::Support.require_rspec_support "matcher_definition"
+
+module RSpec
+  module Support
+    # Extracts info about the number of arguments and allowed/required
+    # keyword args of a given method.
+    #
+    # @private
+    class MethodSignature
+      attr_reader :min_non_kw_args, :max_non_kw_args, :optional_kw_args, :required_kw_args
+
+      def initialize(method)
+        @method           = method
+        @optional_kw_args = []
+        @required_kw_args = []
+        classify_parameters
+      end
+
+      def non_kw_args_arity_description
+        case max_non_kw_args
+        when min_non_kw_args then min_non_kw_args.to_s
+        when INFINITY then "#{min_non_kw_args} or more"
+        else "#{min_non_kw_args} to #{max_non_kw_args}"
+        end
+      end
+
+      def valid_non_kw_args?(positional_arg_count)
+        min_non_kw_args <= positional_arg_count &&
+          positional_arg_count <= max_non_kw_args
+      end
+
+      if RubyFeatures.optional_and_splat_args_supported?
+        def description
+          @description ||= begin
+            parts = []
+
+            unless non_kw_args_arity_description == "0"
+              parts << "arity of #{non_kw_args_arity_description}"
+            end
+
+            if @optional_kw_args.any?
+              parts << "optional keyword args (#{@optional_kw_args.map(&:inspect).join(", ")})"
+            end
+
+            if @required_kw_args.any?
+              parts << "required keyword args (#{@required_kw_args.map(&:inspect).join(", ")})"
+            end
+
+            parts << "any additional keyword args" if @allows_any_kw_args
+
+            parts.join(" and ")
+          end
+        end
+
+        def missing_kw_args_from(given_kw_args)
+          @required_kw_args - given_kw_args
+        end
+
+        def invalid_kw_args_from(given_kw_args)
+          return [] if @allows_any_kw_args
+          given_kw_args - @allowed_kw_args
+        end
+
+        def has_kw_args_in?(args)
+          Hash === args.last && could_contain_kw_args?(args)
+        end
+
+        # Without considering what the last arg is, could it
+        # contain keyword arguments?
+        def could_contain_kw_args?(args)
+          return false if args.count <= min_non_kw_args
+          @allows_any_kw_args || @allowed_kw_args.any?
+        end
+
+        def classify_parameters
+          optional_non_kw_args = @min_non_kw_args = 0
+          @allows_any_kw_args = false
+
+          @method.parameters.each do |(type, name)|
+            case type
+            # def foo(a:)
+            when :keyreq  then @required_kw_args << name
+            # def foo(a: 1)
+            when :key     then @optional_kw_args << name
+            # def foo(**kw_args)
+            when :keyrest then @allows_any_kw_args = true
+            # def foo(a)
+            when :req     then @min_non_kw_args += 1
+            # def foo(a = 1)
+            when :opt     then optional_non_kw_args += 1
+            # def foo(*a)
+            when :rest    then optional_non_kw_args = INFINITY
+            end
+          end
+
+          @max_non_kw_args = @min_non_kw_args  + optional_non_kw_args
+          @allowed_kw_args = @required_kw_args + @optional_kw_args
+        end
+      else
+        def description
+          "arity of #{non_kw_args_arity_description}"
+        end
+
+        def missing_kw_args_from(_given_kw_args)
+          []
+        end
+
+        def invalid_kw_args_from(_given_kw_args)
+          []
+        end
+
+        def has_kw_args_in?(_args)
+          false
+        end
+
+        def could_contain_kw_args?(*)
+          false
+        end
+
+        def classify_parameters
+          arity = @method.arity
+          if arity < 0
+            # `~` inverts the one's complement and gives us the
+            # number of required args
+            @min_non_kw_args = ~arity
+            @max_non_kw_args = INFINITY
+          else
+            @min_non_kw_args = arity
+            @max_non_kw_args = arity
+          end
+        end
+      end
+
+      INFINITY = 1 / 0.0
+    end
+
+    # Deals with the slightly different semantics of block arguments.
+    # For methods, arguments are required unless a default value is provided.
+    # For blocks, arguments are optional, even if no default value is provided.
+    #
+    # However, we want to treat block args as required since you virtually
+    # always want to pass a value for each received argument and our
+    # `and_yield` has treated block args as required for many years.
+    #
+    # @api private
+    class BlockSignature < MethodSignature
+      if RubyFeatures.optional_and_splat_args_supported?
+        def classify_parameters
+          super
+          @min_non_kw_args = @max_non_kw_args unless @max_non_kw_args == INFINITY
+        end
+      end
+    end
+
+    # Abstract base class for signature verifiers.
+    #
+    # @api private
+    class MethodSignatureVerifier
+      attr_reader :non_kw_args, :kw_args
+
+      def initialize(signature, args)
+        @signature = signature
+        @non_kw_args, @kw_args = split_args(*args)
+      end
+
+      def valid?
+        missing_kw_args.empty? &&
+          invalid_kw_args.empty? &&
+          valid_non_kw_args?
+      end
+
+      def error_message
+        if missing_kw_args.any?
+          "Missing required keyword arguments: %s" % [
+            missing_kw_args.join(", ")
+          ]
+        elsif invalid_kw_args.any?
+          "Invalid keyword arguments provided: %s" % [
+            invalid_kw_args.join(", ")
+          ]
+        elsif !valid_non_kw_args?
+          "Wrong number of arguments. Expected %s, got %s." % [
+            @signature.non_kw_args_arity_description,
+            non_kw_args.length
+          ]
+        end
+      end
+
+    private
+
+      def valid_non_kw_args?
+        @signature.valid_non_kw_args?(non_kw_args.length)
+      end
+
+      def missing_kw_args
+        @signature.missing_kw_args_from(kw_args)
+      end
+
+      def invalid_kw_args
+        @signature.invalid_kw_args_from(kw_args)
+      end
+
+      def split_args(*args)
+        kw_args = if @signature.has_kw_args_in?(args)
+                    args.pop.keys
+                  else
+                    []
+                  end
+
+        [args, kw_args]
+      end
+    end
+
+    # Figures out wether a given method can accept various arguments.
+    # Surprisingly non-trivial.
+    #
+    # @private
+    StrictSignatureVerifier = MethodSignatureVerifier
+
+    # Allows matchers to be used instead of providing keyword arguments. In
+    # practice, when this happens only the arity of the method is verified.
+    #
+    # @private
+    class LooseSignatureVerifier < MethodSignatureVerifier
+    private
+
+      def split_args(*args)
+        if RSpec::Support.is_a_matcher?(args.last) && @signature.could_contain_kw_args?(args)
+          args.pop
+          @signature = SignatureWithKeywordArgumentsMatcher.new(@signature)
+        end
+
+        super(*args)
+      end
+
+      # If a matcher is used in a signature in place of keyword arguments, all
+      # keyword argument validation needs to be skipped since the matcher is
+      # opaque.
+      #
+      # Instead, keyword arguments will be validated when the method is called
+      # and they are actually known.
+      #
+      # @private
+      class SignatureWithKeywordArgumentsMatcher
+        def initialize(signature)
+          @signature = signature
+        end
+
+        def missing_kw_args_from(_kw_args)
+          []
+        end
+
+        def invalid_kw_args_from(_kw_args)
+          []
+        end
+
+        def non_kw_args_arity_description
+          @signature.non_kw_args_arity_description
+        end
+
+        def valid_non_kw_args?(*args)
+          @signature.valid_non_kw_args?(*args)
+        end
+
+        def has_kw_args_in?(args)
+          @signature.has_kw_args_in?(args)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/recursive_const_methods.rb b/rspec-support/lib/rspec/support/recursive_const_methods.rb
new file mode 100644
index 0000000..f88abfe
--- /dev/null
+++ b/rspec-support/lib/rspec/support/recursive_const_methods.rb
@@ -0,0 +1,76 @@
+module RSpec
+  module Support
+    # Provides recursive constant lookup methods useful for
+    # constant stubbing.
+    module RecursiveConstMethods
+      # We only want to consider constants that are defined directly on a
+      # particular module, and not include top-level/inherited constants.
+      # Unfortunately, the constant API changed between 1.8 and 1.9, so
+      # we need to conditionally define methods to ignore the top-level/inherited
+      # constants.
+      #
+      # Given:
+      #   class A; B = 1; end
+      #   class C < A; end
+      #
+      # On 1.8:
+      #   - C.const_get("Hash") # => ::Hash
+      #   - C.const_defined?("Hash") # => false
+      #   - C.constants # => ["B"]
+      #   - None of these methods accept the extra `inherit` argument
+      # On 1.9:
+      #   - C.const_get("Hash") # => ::Hash
+      #   - C.const_defined?("Hash") # => true
+      #   - C.const_get("Hash", false) # => raises NameError
+      #   - C.const_defined?("Hash", false) # => false
+      #   - C.constants # => [:B]
+      #   - C.constants(false) #=> []
+      if Module.method(:const_defined?).arity == 1
+        def const_defined_on?(mod, const_name)
+          mod.const_defined?(const_name)
+        end
+
+        def get_const_defined_on(mod, const_name)
+          return mod.const_get(const_name) if const_defined_on?(mod, const_name)
+
+          raise NameError, "uninitialized constant #{mod.name}::#{const_name}"
+        end
+
+        def constants_defined_on(mod)
+          mod.constants.select { |c| const_defined_on?(mod, c) }
+        end
+      else
+        def const_defined_on?(mod, const_name)
+          mod.const_defined?(const_name, false)
+        end
+
+        def get_const_defined_on(mod, const_name)
+          mod.const_get(const_name, false)
+        end
+
+        def constants_defined_on(mod)
+          mod.constants(false)
+        end
+      end
+
+      def recursive_const_get(const_name)
+        normalize_const_name(const_name).split('::').inject(Object) do |mod, name|
+          get_const_defined_on(mod, name)
+        end
+      end
+
+      def recursive_const_defined?(const_name)
+        parts = normalize_const_name(const_name).split('::')
+        parts.inject([Object, '']) do |(mod, full_name), name|
+          yield(full_name, name) if block_given? && !(Module === mod)
+          return false unless const_defined_on?(mod, name)
+          [get_const_defined_on(mod, name), [mod, name].join('::')]
+        end
+      end
+
+      def normalize_const_name(const_name)
+        const_name.sub(/\A::/, '')
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/ruby_features.rb b/rspec-support/lib/rspec/support/ruby_features.rb
new file mode 100644
index 0000000..9df13dc
--- /dev/null
+++ b/rspec-support/lib/rspec/support/ruby_features.rb
@@ -0,0 +1,116 @@
+module RSpec
+  module Support
+    # @api private
+    #
+    # Provides query methods for different OS or OS features.
+    module OS
+      module_function
+
+      def windows?
+        RbConfig::CONFIG['host_os'] =~ /cygwin|mswin|mingw|bccwin|wince|emx/
+      end
+
+      def windows_file_path?
+        ::File::ALT_SEPARATOR == '\\'
+      end
+    end
+
+    # @api private
+    #
+    # Provides query methods for different rubies
+    module Ruby
+      module_function
+
+      def jruby?
+        RUBY_PLATFORM == 'java'
+      end
+
+      def rbx?
+        defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+      end
+
+      def non_mri?
+        !mri?
+      end
+
+      def mri?
+        !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
+      end
+    end
+
+    # @api private
+    #
+    # Provides query methods for ruby features that differ among
+    # implementations.
+    module RubyFeatures
+      module_function
+
+      def optional_and_splat_args_supported?
+        Method.method_defined?(:parameters)
+      end
+
+      def caller_locations_supported?
+        respond_to?(:caller_locations, true)
+      end
+
+      if Ruby.mri?
+        def kw_args_supported?
+          RUBY_VERSION >= '2.0.0'
+        end
+
+        def required_kw_args_supported?
+          RUBY_VERSION >= '2.1.0'
+        end
+
+        def supports_rebinding_module_methods?
+          RUBY_VERSION.to_i >= 2
+        end
+      else
+        # RBX / JRuby et al support is unknown for keyword arguments
+        # rubocop:disable Lint/Eval
+        begin
+          eval("o = Object.new; def o.m(a: 1); end;"\
+               " raise SyntaxError unless o.method(:m).parameters.include?([:key, :a])")
+
+          def kw_args_supported?
+            true
+          end
+        rescue SyntaxError
+          def kw_args_supported?
+            false
+          end
+        end
+
+        begin
+          eval("o = Object.new; def o.m(a: ); end;"\
+               "raise SyntaxError unless o.method(:m).parameters.include?([:keyreq, :a])")
+
+          def required_kw_args_supported?
+            true
+          end
+        rescue SyntaxError
+          def required_kw_args_supported?
+            false
+          end
+        end
+
+        begin
+          Module.new { def foo; end }.instance_method(:foo).bind(Object.new)
+
+          def supports_rebinding_module_methods?
+            true
+          end
+        rescue TypeError
+          def supports_rebinding_module_methods?
+            false
+          end
+        end
+        # rubocop:enable Lint/Eval
+      end
+
+      def module_prepends_supported?
+        Module.method_defined?(:prepend) || Module.private_method_defined?(:prepend)
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec.rb b/rspec-support/lib/rspec/support/spec.rb
new file mode 100644
index 0000000..3f90aa5
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec.rb
@@ -0,0 +1,76 @@
+require 'rspec/support'
+RSpec::Support.require_rspec_support "spec/deprecation_helpers"
+RSpec::Support.require_rspec_support "spec/with_isolated_stderr"
+RSpec::Support.require_rspec_support "spec/stderr_splitter"
+RSpec::Support.require_rspec_support "spec/formatting_support"
+RSpec::Support.require_rspec_support "spec/with_isolated_directory"
+RSpec::Support.require_rspec_support "ruby_features"
+
+warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr)
+
+RSpec.configure do |c|
+  c.include RSpecHelpers
+  c.include RSpec::Support::WithIsolatedStdErr
+  c.include RSpec::Support::FormattingSupport
+
+  unless defined?(Debugger) # debugger causes warnings when used
+    c.before do
+      warning_preventer.reset!
+    end
+
+    c.after do |example|
+      warning_preventer.verify_example!(example)
+    end
+  end
+
+  if c.files_to_run.one?
+    c.full_backtrace = true
+    c.default_formatter = 'doc'
+  end
+
+  c.filter_run :focus
+  c.run_all_when_everything_filtered = true
+
+  c.define_derived_metadata :failing_on_appveyor do |meta|
+    meta[:pending] ||= "This spec fails on AppVeyor and needs someone to fix it."
+  end if ENV['APPVEYOR']
+end
+
+module RSpec
+  module Support
+    module Spec
+      def self.setup_simplecov(&block)
+        # Simplecov emits some ruby warnings when loaded, so silence them.
+        old_verbose, $VERBOSE = $VERBOSE, false
+
+        return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' || RUBY_ENGINE != 'ruby'
+
+        # Don't load it when we're running a single isolated
+        # test file rather than the whole suite.
+        return if RSpec.configuration.files_to_run.one?
+
+        require 'simplecov'
+        start_simplecov(&block)
+      rescue LoadError
+        warn "Simplecov could not be loaded"
+      ensure
+        $VERBOSE = old_verbose
+      end
+
+      def self.start_simplecov(&block)
+        SimpleCov.start do
+          add_filter "./bundle/"
+          add_filter "./tmp/"
+          add_filter do |source_file|
+            # Filter out `spec` directory except when it is under `lib`
+            # (as is the case in rspec-support)
+            source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/')
+          end
+
+          instance_eval(&block) if block
+        end
+      end
+      private_class_method :start_simplecov
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/deprecation_helpers.rb b/rspec-support/lib/rspec/support/spec/deprecation_helpers.rb
new file mode 100644
index 0000000..8453089
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/deprecation_helpers.rb
@@ -0,0 +1,60 @@
+module RSpecHelpers
+  def expect_no_deprecation
+    expect(RSpec.configuration.reporter).not_to receive(:deprecation)
+  end
+
+  def expect_deprecation_with_call_site(file, line, snippet=//)
+    expect(RSpec.configuration.reporter).to receive(:deprecation) do |options|
+      expect(options[:call_site]).to include([file, line].join(':'))
+      expect(options[:deprecated]).to match(snippet)
+    end
+  end
+
+  def expect_deprecation_without_call_site(snippet=//)
+    expect(RSpec.configuration.reporter).to receive(:deprecation) do |options|
+      expect(options[:call_site]).to eq nil
+      expect(options[:deprecated]).to match(snippet)
+    end
+  end
+
+  def expect_warn_deprecation_with_call_site(file, line, snippet=//)
+    expect(RSpec.configuration.reporter).to receive(:deprecation) do |options|
+      message = options[:message]
+      expect(message).to match(snippet)
+      expect(message).to include([file, line].join(':'))
+    end
+  end
+
+  def expect_warn_deprecation(snippet=//)
+    expect(RSpec.configuration.reporter).to receive(:deprecation) do |options|
+      message = options[:message]
+      expect(message).to match(snippet)
+    end
+  end
+
+  def allow_deprecation
+    allow(RSpec.configuration.reporter).to receive(:deprecation)
+  end
+
+  def expect_no_deprecations
+    expect(RSpec.configuration.reporter).not_to receive(:deprecation)
+  end
+
+  def expect_warning_without_call_site(expected=//)
+    expect(::Kernel).to receive(:warn) do |message|
+      expect(message).to match expected
+      expect(message).to_not match(/Called from/)
+    end
+  end
+
+  def expect_warning_with_call_site(file, line, expected=//)
+    expect(::Kernel).to receive(:warn) do |message|
+      expect(message).to match expected
+      expect(message).to match(/Called from #{file}:#{line}/)
+    end
+  end
+
+  def allow_warning
+    allow(::Kernel).to receive(:warn)
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/formatting_support.rb b/rspec-support/lib/rspec/support/spec/formatting_support.rb
new file mode 100644
index 0000000..7e61cef
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/formatting_support.rb
@@ -0,0 +1,9 @@
+module RSpec
+  module Support
+    module FormattingSupport
+      def dedent(string)
+        string.gsub(/^\s+\|/, '').chomp
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/in_sub_process.rb b/rspec-support/lib/rspec/support/spec/in_sub_process.rb
new file mode 100644
index 0000000..eb4de61
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/in_sub_process.rb
@@ -0,0 +1,47 @@
+module RSpec
+  module Support
+    module InSubProcess
+      if Process.respond_to?(:fork) && !(Ruby.jruby? && RUBY_VERSION == '1.8.7')
+
+        # Useful as a way to isolate a global change to a subprocess.
+
+        # rubocop:disable MethodLength
+        def in_sub_process(prevent_warnings=true)
+          readme, writeme = IO.pipe
+
+          pid = Process.fork do
+            exception = nil
+            warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr)
+
+            begin
+              yield
+              warning_preventer.verify_example!(self) if prevent_warnings
+            rescue Exception => e
+              exception = e
+            end
+
+            writeme.write Marshal.dump(exception)
+
+            readme.close
+            writeme.close
+            exit! # prevent at_exit hooks from running (e.g. minitest)
+          end
+
+          writeme.close
+          Process.waitpid(pid)
+
+          exception = Marshal.load(readme.read)
+          readme.close
+
+          raise exception if exception
+        end
+      else
+        def in_sub_process(*)
+          skip "This spec requires forking to work properly, " \
+               "and your platform does not support forking"
+        end
+      end
+      # rubocop:enable MethodLength
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/prevent_load_time_warnings.rb b/rspec-support/lib/rspec/support/spec/prevent_load_time_warnings.rb
new file mode 100644
index 0000000..1edd46d
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/prevent_load_time_warnings.rb
@@ -0,0 +1,56 @@
+require 'rspec/support/spec/shell_out'
+
+module RSpec
+  module Support
+    module WarningsPrevention
+      def files_to_require_for(lib, sub_dir)
+        slash         = File::SEPARATOR
+        lib_path_re   = /#{slash + lib}[^#{slash}]*#{slash}lib/
+        load_path     = $LOAD_PATH.grep(lib_path_re).first
+        directory     = load_path.sub(/lib$/, sub_dir)
+        files         = Dir["#{directory}/**/*.rb"]
+        extract_regex = /#{Regexp.escape(directory) + File::SEPARATOR}(.+)\.rb$/
+
+        # We sort to ensure the files are loaded in a consistent order, regardless
+        # of OS. Otherwise, it could load in a different order on Travis than
+        # locally, and potentially trigger a "circular require considered harmful"
+        # warning or similar.
+        files.sort.map { |file| file[extract_regex, 1] }
+      end
+    end
+  end
+end
+
+RSpec.shared_examples_for "a library that issues no warnings when loaded" do |lib, *preamble_stmnts|
+  include RSpec::Support::ShellOut
+  include RSpec::Support::WarningsPrevention
+
+  define_method :expect_no_warnings_from_files_in do |sub_dir, *pre_stmnts|
+    # We want to explicitly load every file because each lib has some files that
+    # aren't automatically loaded, instead being delayed based on an autoload
+    # (such as for rspec-expectations' matchers) or based on a config option
+    # (e.g. `config.mock_with :rr` => 'rspec/core/mocking_adapters/rr').
+    files_to_require = files_to_require_for(lib, sub_dir)
+    statements = pre_stmnts + files_to_require.map do |file|
+      "require '#{file}'"
+    end
+
+    command = statements.join("; ")
+
+    stdout, stderr, status = with_env 'NO_COVERAGE' => '1' do
+      run_ruby_with_current_load_path(command, "-w")
+    end
+
+    expect(stdout).to eq("")
+    expect(stderr).to eq("")
+    expect(status.exitstatus).to eq(0)
+  end
+
+  it "issues no warnings when loaded", :slow do
+    expect_no_warnings_from_files_in "lib", *preamble_stmnts
+  end
+
+  it "issues no warnings when the spec files are loaded", :slow do
+    expect_no_warnings_from_files_in "spec", "require 'rspec/core'; require 'spec_helper'"
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/shell_out.rb b/rspec-support/lib/rspec/support/spec/shell_out.rb
new file mode 100644
index 0000000..2808ff7
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/shell_out.rb
@@ -0,0 +1,69 @@
+require 'open3'
+require 'rake/file_utils'
+require 'shellwords'
+
+module RSpec
+  module Support
+    module ShellOut
+      def with_env(vars)
+        original = ENV.to_hash
+        vars.each { |k, v| ENV[k] = v }
+
+        begin
+          yield
+        ensure
+          ENV.replace(original)
+        end
+      end
+
+      if Open3.respond_to?(:capture3) # 1.9+
+        def shell_out(*command)
+          stdout, stderr, status = Open3.capture3(*command)
+          return stdout, filter(stderr), status
+        end
+      else # 1.8.7
+        def shell_out(*command)
+          stdout = stderr = nil
+
+          Open3.popen3(*command) do |_in, out, err|
+            stdout = out.read
+            stderr = err.read
+          end
+
+          # popen3 doesn't provide the exit status so we fake it out.
+          status = instance_double(Process::Status, :exitstatus => 0)
+          return stdout, filter(stderr), status
+        end
+      end
+
+      def run_ruby_with_current_load_path(ruby_command, *flags)
+        command = [
+          FileUtils::RUBY,
+          "-I#{$LOAD_PATH.map(&:shellescape).join(File::PATH_SEPARATOR)}",
+          "-e", ruby_command, *flags
+        ]
+
+        # Unset these env vars because `ruby -w` will issue warnings whenever
+        # they are set to non-default values.
+        with_env 'RUBY_GC_HEAP_FREE_SLOTS' => nil, 'RUBY_GC_MALLOC_LIMIT' => nil,
+                 'RUBY_FREE_MIN' => nil do
+          shell_out(*command)
+        end
+      end
+
+    private
+
+      if Ruby.jruby?
+        def filter(output)
+          output.each_line.reject do |line|
+            line.include?("lib/ruby/shared/rubygems/defaults/jruby")
+          end.join($/)
+        end
+      else
+        def filter(output)
+          output
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/stderr_splitter.rb b/rspec-support/lib/rspec/support/spec/stderr_splitter.rb
new file mode 100644
index 0000000..978a07e
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/stderr_splitter.rb
@@ -0,0 +1,63 @@
+require 'stringio'
+
+module RSpec
+  module Support
+    class StdErrSplitter
+      def initialize(original)
+        @orig_stderr    = original
+        @output_tracker = ::StringIO.new
+      end
+
+      respond_to_name = (::RUBY_VERSION.to_f < 1.9) ? :respond_to? : :respond_to_missing?
+      define_method respond_to_name do |*args|
+        @orig_stderr.respond_to?(*args) || super(*args)
+      end
+
+      def method_missing(name, *args, &block)
+        @output_tracker.__send__(name, *args, &block) if @output_tracker.respond_to?(name)
+        @orig_stderr.__send__(name, *args, &block)
+      end
+
+      def ==(other)
+        @orig_stderr == other
+      end
+
+      def reopen(*args)
+        reset!
+        @orig_stderr.reopen(*args)
+      end
+
+      # To work around JRuby error:
+      # can't convert RSpec::Support::StdErrSplitter into String
+      def to_io
+        @orig_stderr.to_io
+      end
+
+      # To work around JRuby error:
+      # TypeError: $stderr must have write method, RSpec::StdErrSplitter given
+      def write(line)
+        return if line =~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG
+
+        @orig_stderr.write(line)
+        @output_tracker.write(line)
+      end
+
+      def has_output?
+        !output.empty?
+      end
+
+      def reset!
+        @output_tracker = ::StringIO.new
+      end
+
+      def verify_example!(example)
+        example.send(:fail, "Warnings were generated: #{output}") if has_output?
+        reset!
+      end
+
+      def output
+        @output_tracker.string
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/with_isolated_directory.rb b/rspec-support/lib/rspec/support/spec/with_isolated_directory.rb
new file mode 100644
index 0000000..c0a2bda
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/with_isolated_directory.rb
@@ -0,0 +1,9 @@
+require 'tmpdir'
+
+RSpec.shared_context "isolated directory", :isolated_directory => true do
+  around do |ex|
+    Dir.mktmpdir do |tmp_dir|
+      Dir.chdir(tmp_dir, &ex)
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/spec/with_isolated_stderr.rb b/rspec-support/lib/rspec/support/spec/with_isolated_stderr.rb
new file mode 100644
index 0000000..8884c2f
--- /dev/null
+++ b/rspec-support/lib/rspec/support/spec/with_isolated_stderr.rb
@@ -0,0 +1,13 @@
+module RSpec
+  module Support
+    module WithIsolatedStdErr
+      def with_isolated_stderr
+        original = $stderr
+        $stderr = StringIO.new
+        yield
+      ensure
+        $stderr = original
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/version.rb b/rspec-support/lib/rspec/support/version.rb
new file mode 100644
index 0000000..7a87e0a
--- /dev/null
+++ b/rspec-support/lib/rspec/support/version.rb
@@ -0,0 +1,7 @@
+module RSpec
+  module Support
+    module Version
+      STRING = '3.2.2'
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/version_checker.rb b/rspec-support/lib/rspec/support/version_checker.rb
new file mode 100644
index 0000000..679211e
--- /dev/null
+++ b/rspec-support/lib/rspec/support/version_checker.rb
@@ -0,0 +1,53 @@
+module RSpec
+  module Support
+    LibraryVersionTooLowError = Class.new(StandardError)
+
+    # @private
+    class VersionChecker
+      def initialize(library_name, library_version, min_patch_level)
+        @library_name, @library_version = library_name, library_version
+        @min_patch_level = min_patch_level
+
+        @major,     @minor,     @patch     = parse_version(library_version)
+        @min_major, @min_minor, @min_patch = parse_version(min_patch_level)
+
+        @comparison_result = compare_version
+      end
+
+      def check_version!
+        raise_too_low_error if too_low?
+      end
+
+    private
+
+      def too_low?
+        @comparison_result == :too_low
+      end
+
+      def raise_too_low_error
+        raise LibraryVersionTooLowError,
+              "You are using #{@library_name} #{@library_version}. " \
+              "RSpec requires version #{version_requirement}."
+      end
+
+      def compare_version
+        case
+        when @major < @min_major then :too_low
+        when @major > @min_major then :ok
+        when @minor < @min_minor then :too_low
+        when @minor > @min_minor then :ok
+        when @patch < @min_patch then :too_low
+        else :ok
+        end
+      end
+
+      def version_requirement
+        ">= #{@min_patch_level}"
+      end
+
+      def parse_version(version)
+        version.split('.').map { |v| v.to_i }
+      end
+    end
+  end
+end
diff --git a/rspec-support/lib/rspec/support/warnings.rb b/rspec-support/lib/rspec/support/warnings.rb
new file mode 100644
index 0000000..1d0a632
--- /dev/null
+++ b/rspec-support/lib/rspec/support/warnings.rb
@@ -0,0 +1,39 @@
+require 'rspec/support'
+RSpec::Support.require_rspec_support "caller_filter"
+
+module RSpec
+  module Support
+    module Warnings
+      def deprecate(deprecated, options={})
+        warn_with "DEPRECATION: #{deprecated} is deprecated.", options
+      end
+
+      # @private
+      #
+      # Used internally to print deprecation warnings
+      # when rspec-core isn't loaded
+      def warn_deprecation(message, options={})
+        warn_with "DEPRECATION: \n #{message}", options
+      end
+
+      # @private
+      #
+      # Used internally to print warnings
+      def warning(text, options={})
+        warn_with "WARNING: #{text}.", options
+      end
+
+      # @private
+      #
+      # Used internally to print longer warnings
+      def warn_with(message, options={})
+        call_site = options.fetch(:call_site) { CallerFilter.first_non_rspec_line }
+        message << " Use #{options[:replacement]} instead." if options[:replacement]
+        message << " Called from #{call_site}." if call_site
+        ::Kernel.warn message
+      end
+    end
+  end
+
+  extend RSpec::Support::Warnings
+end
diff --git a/rspec-support/maintenance-branch b/rspec-support/maintenance-branch
new file mode 100644
index 0000000..ad4dc0e
--- /dev/null
+++ b/rspec-support/maintenance-branch
@@ -0,0 +1 @@
+3-2-maintenance
diff --git a/rspec-support/rspec-support.gemspec b/rspec-support/rspec-support.gemspec
new file mode 100644
index 0000000..1495ee0
--- /dev/null
+++ b/rspec-support/rspec-support.gemspec
@@ -0,0 +1,34 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'rspec/support/version'
+
+Gem::Specification.new do |spec|
+  spec.name          = "rspec-support"
+  spec.version       = RSpec::Support::Version::STRING
+  spec.authors       = ["David Chelimsky","Myron Marson","Jon Rowe","Sam Phippen","Xaviery Shay","Bradley Schaefer"]
+  spec.email         = "rspec-users at rubyforge.org"
+  spec.homepage      = "https://github.com/rspec/rspec-support"
+  spec.summary       = "rspec-support-#{RSpec::Support::Version::STRING}"
+  spec.description   = "Support utilities for RSpec gems"
+  spec.license       = "MIT"
+
+  spec.rubyforge_project  = "rspec"
+
+  spec.files         = `git ls-files -- lib/*`.split("\n")
+  spec.files         += %w[README.md LICENSE.txt Changelog.md]
+  spec.test_files    = []
+  spec.rdoc_options  = ["--charset=UTF-8"]
+  spec.require_paths = ["lib"]
+
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  if File.exist?(private_key)
+    spec.signing_key = private_key
+    spec.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
+  end
+
+  spec.required_ruby_version = '>= 1.8.7'
+
+  spec.add_development_dependency "bundler", "~> 1.3"
+  spec.add_development_dependency "rake",    "~> 10.0.0"
+end
diff --git a/rspec-support/script/clone_all_rspec_repos b/rspec-support/script/clone_all_rspec_repos
new file mode 100755
index 0000000..f83d2e9
--- /dev/null
+++ b/rspec-support/script/clone_all_rspec_repos
@@ -0,0 +1,24 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+if is_mri; then
+  pushd ..
+
+  clone_repo "rspec"
+  clone_repo "rspec-core"
+  clone_repo "rspec-expectations"
+  clone_repo "rspec-mocks"
+  clone_repo "rspec-rails"
+
+  if rspec_support_compatible; then
+    clone_repo "rspec-support"
+  fi
+
+  popd
+else
+  echo "Not cloning all repos since we are not on MRI and they are only needed for the MRI build"
+fi
diff --git a/rspec-support/script/functions.sh b/rspec-support/script/functions.sh
new file mode 100644
index 0000000..a96a5c7
--- /dev/null
+++ b/rspec-support/script/functions.sh
@@ -0,0 +1,129 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $SCRIPT_DIR/travis_functions.sh
+source $SCRIPT_DIR/predicate_functions.sh
+
+# idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
+export JRUBY_OPTS="${JRUBY_OPTS} -X-C" # disable JIT since these processes are so short lived
+SPECS_HAVE_RUN_FILE=specs.out
+MAINTENANCE_BRANCH=`cat maintenance-branch`
+
+function clone_repo {
+  if [ ! -d $1 ]; then # don't clone if the dir is already there
+    travis_retry eval "git clone git://github.com/rspec/$1 --depth 1 --branch $MAINTENANCE_BRANCH"
+  fi;
+}
+
+function run_specs_and_record_done {
+  local rspec_bin=bin/rspec
+
+  # rspec-core needs to run with a special script that loads simplecov first,
+  # so that it can instrument rspec-core's code before rspec-core has been loaded.
+  if [ -f script/rspec_with_simplecov ]; then
+    rspec_bin=script/rspec_with_simplecov
+  fi;
+
+  echo "${PWD}/bin/rspec"
+  $rspec_bin spec --backtrace --format progress --profile --format progress --out $SPECS_HAVE_RUN_FILE
+}
+
+function run_cukes {
+  if [ -d features ]; then
+    # force jRuby to use client mode JVM or a compilation mode thats as close as possible,
+    # idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
+    #
+    # Note that we delay setting this until we run the cukes because we've seen
+    # spec failures in our spec suite due to problems with this mode.
+    export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
+
+    echo "${PWD}/bin/cucumber"
+
+    if is_mri_192; then
+      # For some reason we get SystemStackError on 1.9.2 when using
+      # the bin/cucumber approach below. That approach is faster
+      # (as it avoids the bundler tax), so we use it on rubies where we can.
+      bundle exec cucumber --strict
+    else
+      # Prepare RUBYOPT for scenarios that are shelling out to ruby,
+      # and PATH for those that are using `rspec` or `rake`.
+      RUBYOPT="-I${PWD}/../bundle -rbundler/setup" \
+         PATH="${PWD}/bin:$PATH" \
+         bin/cucumber --strict
+    fi
+  fi
+}
+
+function run_specs_one_by_one {
+  echo "Running each spec file, one-by-one..."
+
+  for file in `find spec -iname '*_spec.rb'`; do
+    bin/rspec $file -b --format progress
+  done
+}
+
+function run_spec_suite_for {
+  if [ ! -f ../$1/$SPECS_HAVE_RUN_FILE ]; then # don't rerun specs that have already run
+    echo "Running specs for $1"
+    pushd ../$1
+    unset BUNDLE_GEMFILE
+    bundle_install_flags=`cat .travis.yml | grep bundler_args | tr -d '"' | grep -o " .*"`
+    travis_retry eval "bundle install $bundle_install_flags"
+    run_specs_and_record_done
+    popd
+  fi;
+}
+
+function check_documentation_coverage {
+  echo "bin/yard stats --list-undoc"
+
+  bin/yard stats --list-undoc | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      coverage ||= line[/([\d\.]+)% documented/, 1]
+      puts line
+    end
+
+    unless Float(coverage) == 100
+      puts \"\n\nMissing documentation coverage (currently at #{coverage}%)\"
+      exit(1)
+    end
+
+    if has_warnings
+      puts \"\n\nYARD emitted documentation warnings.\"
+      exit(1)
+    end
+  "
+
+  # Some warnings only show up when generating docs, so do that as well.
+  bin/yard doc --no-cache | ruby -e "
+    while line = gets
+      has_warnings ||= line.start_with?('[warn]:')
+      has_errors   ||= line.start_with?('[error]:')
+      puts line
+    end
+
+    if has_warnings || has_errors
+      puts \"\n\nYARD emitted documentation warnings or errors.\"
+      exit(1)
+    end
+  "
+}
+
+function check_style_and_lint {
+  echo "bin/rubucop lib"
+  bin/rubocop lib
+}
+
+function run_all_spec_suites {
+  fold "one-by-one specs" run_specs_one_by_one
+  fold "rspec-core specs" run_spec_suite_for "rspec-core"
+  fold "rspec-expectations specs" run_spec_suite_for "rspec-expectations"
+  fold "rspec-mocks specs" run_spec_suite_for "rspec-mocks"
+  fold "rspec-rails specs" run_spec_suite_for "rspec-rails"
+
+  if rspec_support_compatible; then
+    fold "rspec-support specs" run_spec_suite_for "rspec-support"
+  fi
+}
diff --git a/rspec-support/script/predicate_functions.sh b/rspec-support/script/predicate_functions.sh
new file mode 100644
index 0000000..fc5d372
--- /dev/null
+++ b/rspec-support/script/predicate_functions.sh
@@ -0,0 +1,64 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+function is_mri {
+  if ruby -e "exit(!defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby')"; then
+    # RUBY_ENGINE only returns 'ruby' on MRI.
+    # MRI 1.8.7 lacks the constant but all other rubies have it (including JRuby in 1.8 mode)
+    return 0
+  else
+    return 1
+  fi;
+}
+
+function is_mri_192 {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION == '1.9.2')"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function is_mri_2plus {
+  if is_mri; then
+    if ruby -e "exit(RUBY_VERSION.to_f > 2.0)"; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function rspec_support_compatible {
+  if [ "$MAINTENANCE_BRANCH" != "2-99-maintenance" ] && [ "$MAINTENANCE_BRANCH" != "2-14-maintenance" ]; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+function documentation_enforced {
+  if [ -x ./bin/yard ]; then
+    if is_mri_2plus; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    return 1
+  fi
+}
+
+function style_and_lint_enforced {
+ if [ -x ./bin/rubocop ]; then
+   return 0
+ else
+   return 1
+ fi
+}
diff --git a/rspec-support/script/run_build b/rspec-support/script/run_build
new file mode 100755
index 0000000..e1edcef
--- /dev/null
+++ b/rspec-support/script/run_build
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+set -e
+source script/functions.sh
+
+# Allow repos to override the default functions and add their own
+if [ -f script/custom_build_functions.sh ]; then
+  source script/custom_build_functions.sh
+fi
+
+fold "specs" run_specs_and_record_done
+fold "cukes" run_cukes
+
+if documentation_enforced; then
+  fold "doc check" check_documentation_coverage
+fi
+
+if style_and_lint_enforced; then
+  fold "rubocop" check_style_and_lint
+fi
+
+if is_mri; then
+  run_all_spec_suites
+else
+  echo "Skipping the rest of the build on non-MRI rubies"
+fi
diff --git a/rspec-support/script/travis_functions.sh b/rspec-support/script/travis_functions.sh
new file mode 100644
index 0000000..77829b3
--- /dev/null
+++ b/rspec-support/script/travis_functions.sh
@@ -0,0 +1,69 @@
+# This file was generated on 2015-01-07T22:08:46-08:00 from the rspec-dev repo.
+# DO NOT modify it by hand as your changes will get lost the next time it is generated.
+
+# Taken from:
+# https://github.com/travis-ci/travis-build/blob/e9314616e182a23e6a280199cd9070bfc7cae548/lib/travis/build/script/templates/header.sh#L34-L53
+travis_retry() {
+  local result=0
+  local count=1
+  while [ $count -le 3 ]; do
+    [ $result -ne 0 ] && {
+      echo -e "\n\033[33;1mThe command \"$@\" failed. Retrying, $count of 3.\033[0m\n" >&2
+    }
+    "$@"
+    result=$?
+    [ $result -eq 0 ] && break
+    count=$(($count + 1))
+    sleep 1
+  done
+
+  [ $count -eq 3 ] && {
+    echo "\n\033[33;1mThe command \"$@\" failed 3 times.\033[0m\n" >&2
+  }
+
+  return $result
+}
+
+# Taken from https://github.com/vcr/vcr/commit/fa96819c92b783ec0c794f788183e170e4f684b2
+# and https://github.com/vcr/vcr/commit/040aaac5370c68cd13c847c076749cd547a6f9b1
+nano_cmd="$(type -p gdate date | head -1)"
+nano_format="+%s%N"
+[ "$(uname -s)" != "Darwin" ] || nano_format="${nano_format/%N/000000000}"
+
+travis_time_start() {
+  travis_timer_id=$(printf %08x $(( RANDOM * RANDOM )))
+  travis_start_time=$($nano_cmd -u "$nano_format")
+  printf "travis_time:start:%s\r\e[0m" $travis_timer_id
+}
+
+travis_time_finish() {
+  local travis_end_time=$($nano_cmd -u "$nano_format")
+  local duration=$(($travis_end_time-$travis_start_time))
+  printf "travis_time:end:%s:start=%s,finish=%s,duration=%s\r\e[0m" \
+    $travis_timer_id $travis_start_time $travis_end_time $duration
+}
+
+fold() {
+  local name="$1"
+  local status=0
+  shift 1
+  if [ -n "$TRAVIS" ]; then
+    printf "travis_fold:start:%s\r\e[0m" "$name"
+    travis_time_start
+  fi
+
+  "$@"
+  status=$?
+
+  [ -z "$TRAVIS" ] || travis_time_finish
+
+  if [ "$status" -eq 0 ]; then
+    if [ -n "$TRAVIS" ]; then
+      printf "travis_fold:end:%s\r\e[0m" "$name"
+    fi
+  else
+    STATUS="$status"
+  fi
+
+  return $status
+}
diff --git a/rspec-support/spec/rspec/support/caller_filter_spec.rb b/rspec-support/spec/rspec/support/caller_filter_spec.rb
new file mode 100644
index 0000000..759cd4f
--- /dev/null
+++ b/rspec-support/spec/rspec/support/caller_filter_spec.rb
@@ -0,0 +1,74 @@
+require 'spec_helper'
+require 'fileutils'
+require 'rspec/support/caller_filter'
+
+module RSpec
+  describe CallerFilter do
+    it 'can receive skip_frames and increment arguments' do
+      expect(RSpec::CallerFilter.first_non_rspec_line(1, 5)).to include("#{__FILE__}:#{__LINE__}")
+    end
+
+    it 'returns the immediate caller when called from a spec' do
+      expect(RSpec::CallerFilter.first_non_rspec_line).to include("#{__FILE__}:#{__LINE__}")
+    end
+
+    describe "the filtering regex" do
+      def ruby_files_in_lib(lib)
+        # http://rubular.com/r/HYpUMftlG2
+        path = $LOAD_PATH.find { |p| p.match(/\/rspec-#{lib}(-[a-f0-9]+)?\/lib/) }
+
+        Dir["#{path}/**/*.rb"].sort.tap do |files|
+          # Just a sanity check...
+          expect(files.count).to be > 5
+        end
+      end
+
+      def unmatched_from(files)
+        files.reject { |file| file.match(CallerFilter::IGNORE_REGEX) }
+      end
+
+      %w[ core mocks expectations support ].each do |lib|
+        it "matches all ruby files in rspec-#{lib}" do
+          files = ruby_files_in_lib(lib)
+          expect(unmatched_from files).to eq([])
+        end
+      end
+
+      it "does not match other ruby files" do
+        files = %w[
+          /path/to/lib/rspec/some-extension/foo.rb
+          /path/to/spec/rspec/core/some_spec.rb
+        ]
+
+        expect(unmatched_from files).to eq(files)
+      end
+
+      def in_rspec_support_lib(name)
+        root = File.expand_path("../../../../lib/rspec/support", __FILE__)
+        dir = "#{root}/#{name}"
+        FileUtils.mkdir(dir)
+        yield dir
+      ensure
+        FileUtils.rm_rf(dir)
+      end
+
+      it 'does not match rubygems lines from `require` statements' do
+        with_isolated_stderr do
+          require 'rubygems' # ensure rubygems is laoded
+        end
+
+        in_rspec_support_lib("test_dir") do |dir|
+          File.open("#{dir}/file.rb", "w") do |file|
+            file.write("$_caller_filter = RSpec::CallerFilter.first_non_rspec_line")
+          end
+
+          $_caller_filter = nil
+
+          expect {
+            require "rspec/support/test_dir/file"
+          }.to change { $_caller_filter }.to(include "#{__FILE__}:#{__LINE__ - 1}")
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/differ_spec.rb b/rspec-support/spec/rspec/support/differ_spec.rb
new file mode 100644
index 0000000..8d927af
--- /dev/null
+++ b/rspec-support/spec/rspec/support/differ_spec.rb
@@ -0,0 +1,366 @@
+# encoding: utf-8
+require 'spec_helper'
+require 'ostruct'
+require 'timeout'
+require 'rspec/support/differ'
+
+module RSpec
+  module Support
+    describe Differ do
+      describe '#diff' do
+        let(:differ) { RSpec::Support::Differ.new }
+
+        it "outputs unified diff of two strings" do
+          expected = "foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
+          actual   = "foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
+
+          expected_diff = <<-'EOD'
+
+
+@@ -1,6 +1,6 @@
+ foo
+-zap
+ bar
++zap
+ this
+ is
+ soo
+@@ -9,6 +9,5 @@
+ equal
+ insert
+ a
+-another
+ line
+EOD
+
+          diff = differ.diff(actual, expected)
+          expect(diff).to eql(expected_diff)
+        end
+
+        it "outputs unified diff of two strings when used multiple times" do
+          expected = "foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
+          actual   = "foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
+
+          expected_diff = dedent(<<-'EOS')
+            |
+            |
+            |@@ -1,6 +1,6 @@
+            | foo
+            |-zap
+            | bar
+            |+zap
+            | this
+            | is
+            | soo
+            |@@ -9,6 +9,5 @@
+            | equal
+            | insert
+            | a
+            |-another
+            | line
+            |
+          EOS
+
+          diff = differ.diff(actual, expected)
+          expect(diff).to eql(expected_diff)
+
+          diff = differ.diff(actual, expected)
+          expect(diff).to eql(expected_diff)
+        end
+
+        it 'does not mutate any instance variables when diffing, so we can reason about it being reused' do
+          expected = "foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
+          actual   = "foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
+
+          expect { differ.diff(actual, expected) }.not_to change { differ_ivars }
+        end
+
+        def differ_ivars
+          Hash[ differ.instance_variables.map do |ivar|
+            [ivar, differ.instance_variable_get(ivar)]
+          end ]
+        end
+
+        if String.method_defined?(:encoding)
+          it "returns an empty string if strings are not multiline" do
+            expected = "Tu avec carte {count} item has".encode('UTF-16LE')
+            actual   = "Tu avec carté {count} itém has".encode('UTF-16LE')
+
+            expect(differ.diff(actual, expected)).to be_empty
+          end
+
+          it 'copes with encoded strings' do
+            expected = "Tu avec carte {count} item has\n".encode('UTF-16LE')
+            actual   = "Tu avec carté {count} itém has\n".encode('UTF-16LE')
+            expect(differ.diff(actual, expected)).to eql(<<-EOD.encode('UTF-16LE'))
+
+@@ -1,2 +1,2 @@
+-Tu avec carte {count} item has
++Tu avec carté {count} itém has
+EOD
+          end
+
+          it 'handles differently encoded strings that are compatible' do
+            expected = "abc\n".encode('us-ascii')
+            actual   = "강인철\n".encode('UTF-8')
+            expect(differ.diff(actual, expected)).to eql "\n@@ -1,2 +1,2 @@\n-abc\n+강인철\n"
+          end
+
+          it 'uses the default external encoding when the two strings have incompatible encodings', :failing_on_appveyor do
+            expected = "Tu avec carte {count} item has\n"
+            actual   = "Tu avec carté {count} itém has\n".encode('UTF-16LE')
+            expect(differ.diff(actual, expected)).to eq("\n@@ -1,2 +1,2 @@\n-Tu avec carte {count} item has\n+Tu avec carté {count} itém has\n")
+            expect(differ.diff(actual, expected).encoding).to eq(Encoding.default_external)
+          end
+
+          it 'handles any encoding error that occurs with a helpful error message' do
+            expect(RSpec::Support::HunkGenerator).to receive(:new).
+              and_raise(Encoding::CompatibilityError)
+            expected = "Tu avec carte {count} item has\n".encode('us-ascii')
+            actual   = "Tu avec carté {count} itém has\n"
+            diff = differ.diff(actual, expected)
+            expect(diff).to match(/Could not produce a diff/)
+            expect(diff).to match(/actual string \(UTF-8\)/)
+            expect(diff).to match(/expected string \(US-ASCII\)/)
+          end
+        end
+
+        it "outputs unified diff message of two objects" do
+          animal_class = Class.new do
+            def initialize(name, species)
+              @name, @species = name, species
+            end
+
+            def inspect
+              <<-EOA
+<Animal
+  name=#{@name},
+  species=#{@species}
+>
+              EOA
+            end
+          end
+
+          expected = animal_class.new "bob", "giraffe"
+          actual   = animal_class.new "bob", "tortoise"
+
+          expected_diff = <<'EOD'
+
+@@ -1,5 +1,5 @@
+ <Animal
+   name=bob,
+-  species=tortoise
++  species=giraffe
+ >
+EOD
+
+          diff = differ.diff(expected,actual)
+          expect(diff).to eq expected_diff
+        end
+
+        it "outputs unified diff message of two arrays" do
+          expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
+          actual   = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango'  , :width, 'very wide'  ]
+
+          expected_diff = <<'EOD'
+
+
+@@ -5,7 +5,7 @@
+  :metasyntactic,
+  "variable",
+  :delta,
+- "tango",
++ "charlie",
+  :width,
+- "very wide"]
++ "quite wide"]
+EOD
+
+          diff = differ.diff(expected,actual)
+          expect(diff).to eq expected_diff
+        end
+
+        it 'outputs a unified diff message for an array which flatten recurses' do
+          klass = Class.new do
+            def to_ary; [self]; end
+            def inspect; "<BrokenObject>"; end
+          end
+          obj = klass.new
+
+          diff = ''
+          Timeout::timeout(1) do
+            diff = differ.diff [obj], []
+          end
+
+          expect(diff).to eq <<-EOD
+
+@@ -1,2 +1,2 @@
+-[]
++[<BrokenObject>]
+EOD
+        end
+
+        it "outputs unified diff message of two hashes" do
+          expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' }
+          actual   = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' }
+
+          expected_diff = <<'EOD'
+
+@@ -1,4 +1,5 @@
+-:delta => "charlotte",
++:baz => "quux",
++:delta => "charlie",
+ :foo => "bar",
+ :metasyntactic => "variable",
+ :width => "quite wide",
+EOD
+
+          diff = differ.diff(expected,actual)
+          expect(diff).to eq expected_diff
+        end
+
+        it 'outputs unified diff message of two hashes with differing encoding', :failing_on_appveyor do
+          expected_diff = %Q{
+@@ -1,2 +1,2 @@
+-"a" => "a",
+#{ (RUBY_VERSION.to_f > 1.8) ?  %Q{+"ö" => "ö"} : '+"\303\266" => "\303\266"' },
+}
+
+          diff = differ.diff({'ö' => 'ö'}, {'a' => 'a'})
+          expect(diff).to eq expected_diff
+        end
+
+        it 'outputs unified diff message of two hashes with encoding different to key encoding', :failing_on_appveyor do
+          expected_diff = %Q{
+@@ -1,2 +1,2 @@
+-:a => "a",
+#{ (RUBY_VERSION.to_f > 1.8) ?  %Q{+\"한글\" => \"한글2\"} : '+"\355\225\234\352\270\200" => "\355\225\234\352\270\2002"' },
+}
+
+          diff = differ.diff({ "한글" => "한글2"}, { :a => "a"})
+          expect(diff).to eq expected_diff
+        end
+
+        it "outputs unified diff message of two hashes with object keys" do
+          expected_diff = %Q{
+@@ -1,2 +1,2 @@
+-["a", "c"] => "b",
++["d", "c"] => "b",
+}
+
+          diff = differ.diff({ ['d','c'] => 'b'}, { ['a','c'] => 'b' })
+          expect(diff).to eq expected_diff
+        end
+
+        it "outputs unified diff of multi line strings" do
+          expected = "this is:\n  one string"
+          actual   = "this is:\n  another string"
+
+          expected_diff = <<'EOD'
+
+@@ -1,3 +1,3 @@
+ this is:
+-  another string
++  one string
+EOD
+
+          diff = differ.diff(expected,actual)
+          expect(diff).to eq expected_diff
+        end
+
+        it "splits items with newlines" do
+          expected_diff = <<'EOD'
+
+@@ -1,3 +1 @@
+-a\nb
+-c\nd
+EOD
+
+          diff = differ.diff [], ["a\nb", "c\nd"]
+          expect(diff).to eql expected_diff
+        end
+
+        it "shows inner arrays on a single line" do
+          expected_diff = <<'EOD'
+
+@@ -1,3 +1 @@
+-a\nb
+-["c\nd"]
+EOD
+
+          diff = differ.diff [], ["a\nb", ["c\nd"]]
+          expect(diff).to eql expected_diff
+        end
+
+        it "returns an empty string if no expected or actual" do
+          diff = differ.diff nil, nil
+
+          expect(diff).to be_empty
+        end
+
+        it "returns an empty string if expected is Numeric" do
+          diff = differ.diff 1, "2"
+
+          expect(diff).to be_empty
+        end
+
+        it "returns an empty string if actual is Numeric" do
+          diff = differ.diff "1", 2
+
+          expect(diff).to be_empty
+        end
+
+        it "returns an empty string if expected or actual are procs" do
+          diff = differ.diff lambda {}, lambda {}
+
+          expect(diff).to be_empty
+        end
+
+        it "returns a String if no diff is returned" do
+          diff = differ.diff 1, 2
+          expect(diff).to be_a(String)
+        end
+
+        it "returns a String if a diff is performed" do
+          diff = differ.diff "a\n", "b\n"
+          expect(diff).to be_a(String)
+        end
+
+        context "with :object_preparer option set" do
+          let(:differ) do
+            RSpec::Support::Differ.new(:object_preparer => lambda { |s| s.to_s.reverse })
+          end
+
+          it "uses the output of object_preparer for diffing" do
+            expected = :foo
+            actual = :poo
+
+            expected_diff = dedent(<<-EOS)
+              |
+              |@@ -1,2 +1,2 @@
+              |-"oop"
+              |+"oof"
+              |
+            EOS
+
+            diff = differ.diff(expected, actual)
+            expect(diff).to eq expected_diff
+          end
+        end
+
+        context "with :color option set" do
+          let(:differ) { RSpec::Support::Differ.new(:color => true) }
+
+          it "outputs colored diffs" do
+            expected = "foo bar baz\n"
+            actual = "foo bang baz\n"
+            expected_diff = "\e[0m\n\e[0m\e[34m@@ -1,2 +1,2 @@\n\e[0m\e[31m-foo bang baz\n\e[0m\e[32m+foo bar baz\n\e[0m"
+
+            diff = differ.diff(expected,actual)
+            expect(diff).to eq expected_diff
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/directory_maker_spec.rb b/rspec-support/spec/rspec/support/directory_maker_spec.rb
new file mode 100644
index 0000000..d133b6e
--- /dev/null
+++ b/rspec-support/spec/rspec/support/directory_maker_spec.rb
@@ -0,0 +1,60 @@
+require "spec_helper"
+require "fileutils"
+
+RSpec::Support.require_rspec_support("directory_maker")
+
+module RSpec::Support
+  describe DirectoryMaker do
+    shared_examples_for "an mkdir_p implementation" do
+      include_context "isolated directory"
+
+      let(:dirname) { File.join(%w[tmp a recursive structure]) }
+
+      def directory_exists?(dirname)
+        File.exist?(dirname) && File.directory?(dirname)
+      end
+
+      it "makes directories recursively" do
+        mkdir_p.call(dirname)
+        expect(directory_exists?(dirname)).to be true
+      end
+
+      it "does not raise if the directory already exists" do
+        Dir.mkdir("tmp")
+        mkdir_p.call(dirname)
+        expect(directory_exists?(dirname)).to be true
+      end
+
+      context "when a file already exists" do
+        before { File.open("tmp", "w") }
+
+        it "raises, as it can't make the directory", :failing_on_appveyor,
+           :pending => false,
+           :skip => (ENV['APPVEYOR'] ? "Failing on AppVeyor but :pending isn't working for some reason" : false) do
+          expect {
+            mkdir_p.call(dirname)
+          }.to raise_error(Errno::EEXIST)
+        end
+      end
+
+      context "when the path specified is absolute" do
+        let(:dirname) { "bees/ponies" }
+
+        it "makes directories recursively" do
+          mkdir_p.call(File.expand_path(dirname))
+          expect(directory_exists?(dirname)).to be true
+        end
+      end
+    end
+
+    describe ".mkdir_p" do
+      subject(:mkdir_p) { DirectoryMaker.method(:mkdir_p) }
+      it_behaves_like "an mkdir_p implementation"
+    end
+
+    describe "FileUtils.mkdir_p" do
+      subject(:mkdir_p) { FileUtils.method(:mkdir_p) }
+      it_behaves_like "an mkdir_p implementation"
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/encoded_string_spec.rb b/rspec-support/spec/rspec/support/encoded_string_spec.rb
new file mode 100644
index 0000000..807cc3d
--- /dev/null
+++ b/rspec-support/spec/rspec/support/encoded_string_spec.rb
@@ -0,0 +1,255 @@
+# encoding: utf-8
+require 'spec_helper'
+require 'rspec/support/encoded_string'
+
+# Special matcher for comparing encoded strings so that
+# we don't run any expectation failures through the Differ,
+# which also relies on EncodedString. Instead, confirm the
+# strings have the same encoding and same bytes.
+RSpec::Matchers.define :be_identical_string do |expected|
+
+  if String.method_defined?(:encoding)
+    match do
+      actual.encoding == expected.encoding &&
+        actual.bytes.to_a == expected.bytes.to_a
+    end
+
+    failure_message do
+      "expected\n#{actual.inspect} (#{actual.encoding.name}) to be identical to\n"\
+        "#{expected.inspect} (#{expected.encoding.name})\n"\
+        "The exact bytes are printed below for more detail:\n"\
+        "#{actual.bytes.to_a}\n"\
+        "#{expected.bytes.to_a}\n"\
+    end
+  else
+    match do |actual|
+      actual.split(//) == expected.split(//)
+    end
+  end
+end
+RSpec::Matchers.alias_matcher :a_string_identical_to, :be_identical_string
+
+module RSpec::Support
+  describe EncodedString do
+    let(:utf8_encoding) { 'UTF-8' }
+
+    delegated_methods = String.instance_methods.map(&:to_s) & %w[eql? lines == encoding empty?]
+    delegated_methods.each do |delegated_method|
+      it "responds to #{delegated_method}" do
+        encoded_string = EncodedString.new("abc", utf8_encoding)
+        expect(encoded_string).to respond_to(delegated_method)
+      end
+    end
+
+    if String.method_defined?(:encoding)
+
+      describe '#source_encoding' do
+        it 'knows the original encoding of the string' do
+          str = EncodedString.new("abc".encode('ASCII-8BIT'), "UTF-8")
+          expect(str.source_encoding.to_s).to eq('ASCII-8BIT')
+        end
+      end
+
+      describe '#to_s' do
+        context 'when encoding a string with invalid bytes in the target encoding' do
+          # see https://github.com/jruby/jruby/blob/c1be61a501/test/mri/ruby/test_transcode.rb#L13
+          let(:source_encoding) { Encoding.find('US-ASCII') }
+          let(:target_encoding) { Encoding.find('UTF-8') }
+          let(:string) { "I have a bad byté\x80".force_encoding(source_encoding) }
+
+          it 'normally raises an EncodedString::InvalidByteSequenceError' do
+            expect {
+              string.encode(target_encoding)
+            }.to raise_error(Encoding::InvalidByteSequenceError)
+          end
+
+          # See JRuby issue https://github.com/jruby/jruby/issues/2580
+          it 'replaces invalid byte sequences with the REPLACE string', :pending => RSpec::Support::Ruby.jruby? do
+            resulting_string = build_encoded_string(string, target_encoding).to_s
+            replacement = EncodedString::REPLACE * 3
+            expected_string = "I have a bad byt#{replacement}".force_encoding(target_encoding)
+            expect(resulting_string).to be_identical_string(expected_string)
+          end
+        end
+
+        context 'when no converter is known for an encoding' do
+          # see https://github.com/rubyspec/rubyspec/blob/91ce9f6549/core/string/shared/encode.rb#L12
+          let(:source_encoding) { Encoding.find('ASCII-8BIT') }
+          let(:no_converter_encoding) { Encoding::Emacs_Mule }
+          let(:string) { "\x80".force_encoding(source_encoding) }
+
+          it 'normally raises an Encoding::ConverterNotFoundError' do
+            expect {
+              string.encode(no_converter_encoding)
+            }.to raise_error(Encoding::ConverterNotFoundError)
+          end
+
+          # See comment above ENCODE_UNCONVERTABLE_BYTES in encoded_string.rb
+          # for why the behavior differs by (MRI) Ruby version.
+          if RUBY_VERSION < '2.1'
+            it 'does nothing' do
+              resulting_string = build_encoded_string(string, no_converter_encoding).to_s
+              expected_string  = "\x80".force_encoding(no_converter_encoding)
+              expect(resulting_string).to be_identical_string(expected_string)
+            end
+          else
+            it 'forces the encoding and replaces invalid characters with the REPLACE string' do
+              resulting_string = build_encoded_string(string, no_converter_encoding).to_s
+              expected_string  = EncodedString::REPLACE.dup.force_encoding(no_converter_encoding)
+              expect(resulting_string).to be_identical_string(expected_string)
+            end
+
+            it 'does not mutate the input string' do
+              expect {
+                build_encoded_string(string, no_converter_encoding)
+              }.not_to change { [string, string.encoding] }
+            end
+          end
+        end
+
+        # see https://github.com/ruby/ruby/blob/34fbf57aaa/transcode.c#L4289
+        # ISO-8859-1 -> UTF-8 -> EUC-JP
+        # "\xa0" NO-BREAK SPACE, which is available in UTF-8 but not in EUC-JP
+        context 'when there is an undefined conversion to the target encoding' do
+          let(:source_encoding) { Encoding.find('ISO-8859-1') }
+          let(:incompatible_encoding) { Encoding.find('EUC-JP') }
+          let(:string) { "\xa0 hi I am not going to work".force_encoding(source_encoding) }
+
+          it 'normally raises an Encoding::UndefinedConversionError' do
+            expect {
+              string.encode(incompatible_encoding)
+            }.to raise_error(Encoding::UndefinedConversionError)
+          end
+
+          it 'replaces all undefines conversions with the REPLACE string' do
+            resulting_string = build_encoded_string(string, incompatible_encoding).to_s
+            replacement = EncodedString::REPLACE
+            expected_string = "#{replacement} hi I am not going to work".force_encoding('EUC-JP')
+            expect(resulting_string).to be_identical_string(expected_string)
+          end
+        end
+      end
+
+      let(:ascii_arrow_symbol) { "\xAE" }
+      let(:utf_8_euro_symbol) { "\xE2\x82\xAC" }
+
+      describe '#<<' do
+        context 'with strings that can be converted to the target encoding' do
+          let(:valid_ascii_string) { "abcde".force_encoding("ASCII-8BIT") }
+          let(:valid_unicode_string) { utf_8_euro_symbol.force_encoding('UTF-8') }
+
+          it 'encodes and appends the string' do
+            resulting_string = build_encoded_string(valid_unicode_string, utf8_encoding) << valid_ascii_string
+            expected_string = "#{utf_8_euro_symbol}abcde".force_encoding('UTF-8')
+            expect(resulting_string).to be_identical_string(expected_string)
+          end
+        end
+
+        context 'with a string that cannot be converted to the target encoding' do
+          context 'when appending a string with an incompatible character encoding' do
+            let(:ascii_string) { ascii_arrow_symbol.force_encoding("ASCII-8BIT") }
+            let(:valid_unicode_string) { utf_8_euro_symbol.force_encoding('UTF-8') }
+
+            it "normally raises an Encoding::CompatibilityError" do
+              expect {
+                valid_unicode_string.encode(utf8_encoding) << ascii_string
+              }.to raise_error(Encoding::CompatibilityError)
+            end
+
+            it 'replaces unconvertable characters with the REPLACE string' do
+              resulting_string = build_encoded_string(valid_unicode_string, utf8_encoding) << ascii_string
+              expected_string = "#{utf_8_euro_symbol}#{EncodedString::REPLACE}"
+              expect(resulting_string).to be_identical_string(expected_string)
+            end
+          end
+        end
+
+        context 'with two ascii strings with a target encoding of UTF-8 ' do
+          it 'has an encoding of UTF-8' do
+            ascii_string = 'abc'.force_encoding("ASCII-8BIT")
+            other_ascii_string = '123'.force_encoding("ASCII-8BIT")
+
+            resulting_string = build_encoded_string(ascii_string, utf8_encoding) << other_ascii_string
+            expected_string = 'abc123'.force_encoding(utf8_encoding)
+            expect(resulting_string).to be_identical_string(expected_string)
+          end
+        end
+      end
+
+      describe '#split' do
+        context 'when there is an undefined conversion to the target encoding' do
+          let(:wrapped_string_template) { "abaaaaaaaaaa%saaaaa" }
+          let(:wrapped_string) { sprintf(wrapped_string_template, ascii_arrow_symbol).force_encoding("ASCII-8BIT") }
+
+          it 'normally raises an Encoding::UndefinedConversionError' do
+            expect {
+              wrapped_string.encode(utf8_encoding)
+            }.to raise_error(Encoding::UndefinedConversionError)
+          end
+
+          it 'splits the string based on the delimiter accounting for encoding' do
+            delimiter = "b".force_encoding(utf8_encoding)
+            resulting_string = build_encoded_string(wrapped_string, utf8_encoding).split(delimiter)
+            exp1, exp2 = sprintf(wrapped_string_template, EncodedString::REPLACE).force_encoding(utf8_encoding).split(delimiter)
+            expect(resulting_string).to match [
+              a_string_identical_to(exp1),
+              a_string_identical_to(exp2)
+            ]
+          end
+        end
+
+        # see https://github.com/rspec/rspec-expectations/blob/f8a1232/spec/rspec/expectations/fail_with_spec.rb#L50
+        #     https://github.com/rspec/rspec-expectations/issues/201
+        #     https://github.com/rspec/rspec-expectations/pull/220
+        context 'with a string that cannot be converted to the target encoding' do
+          let(:binary_poop) {'💩' } # [128169] "\u{1F4A9}"
+          let(:non_ascii_compatible_string) { "This is a pile of poo: #{binary_poop}, yuck".encode("UTF-16LE") }
+
+          it 'normally raises an Encoding::CompatibilityError' do
+            expect {
+              non_ascii_compatible_string.split("\n")
+            }.to raise_error(Encoding::CompatibilityError)
+          end
+
+          it 'makes no changes to the resulting string' do
+            resulting_array = build_encoded_string(non_ascii_compatible_string).split("\n")
+            expect(resulting_array).to match [
+              a_string_identical_to(non_ascii_compatible_string)
+            ]
+          end
+        end
+
+        context 'when the string has an invalid byte sequence' do
+          let(:message_with_invalid_byte_sequence) { "\xEF \255 \xAD I have bad bytes".force_encoding(utf8_encoding) }
+
+          it 'normally raises an ArgumentError' do
+            expect(message_with_invalid_byte_sequence).not_to be_valid_encoding
+            expect {
+              message_with_invalid_byte_sequence.split("\n")
+            }.to raise_error(ArgumentError)
+          end
+
+          it 'replaces invalid bytes with the REPLACE string' do
+            resulting_array = build_encoded_string(message_with_invalid_byte_sequence, utf8_encoding).split("\n")
+            expected_string = "? ? ? I have bad bytes"
+            expect(resulting_array).to match [
+              a_string_identical_to(expected_string)
+            ]
+          end
+        end
+      end
+
+      def build_encoded_string(string, target_encoding = string.encoding)
+        EncodedString.new(string, target_encoding)
+      end
+    else
+
+      describe '#source_encoding' do
+        it 'defaults to US-ASCII' do
+          str = EncodedString.new("abc", "UTF-8")
+          expect(str.source_encoding).to eq('US-ASCII')
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/fuzzy_matcher_spec.rb b/rspec-support/spec/rspec/support/fuzzy_matcher_spec.rb
new file mode 100644
index 0000000..9d13c2b
--- /dev/null
+++ b/rspec-support/spec/rspec/support/fuzzy_matcher_spec.rb
@@ -0,0 +1,184 @@
+require 'spec_helper'
+require 'rspec/support/fuzzy_matcher'
+
+module RSpec
+  module Support
+    describe FuzzyMatcher, ".values_match?" do
+      matcher :match_against do |actual|
+        match { |expected| FuzzyMatcher.values_match?(expected, actual) }
+      end
+
+      it 'returns true when given equal values' do
+        expect(1).to match_against(1.0)
+      end
+
+      it 'returns false when given unequal values that do not provide match logic' do
+        expect(1).not_to match_against(1.1)
+      end
+
+      it 'can match a regex against a string' do
+        expect(/foo/).to match_against("foobar")
+        expect(/foo/).not_to match_against("fobar")
+      end
+
+      it 'can match a regex against itself' do
+        expect(/foo/).to match_against(/foo/)
+        expect(/foo/).not_to match_against(/bar/)
+      end
+
+      it 'can match a class against an instance' do
+        expect(String).to match_against("foo")
+        expect(String).not_to match_against(123)
+      end
+
+      it 'can match a class against itself' do
+        expect(String).to match_against(String)
+        expect(String).not_to match_against(Regexp)
+      end
+
+      it 'can match against a matcher' do
+        expect(be_within(0.1).of(2)).to match_against(2.05)
+        expect(be_within(0.1).of(2)).not_to match_against(2.15)
+      end
+
+      it 'does not ask the second argument if it fuzzy matches (===)' do
+        expect("foo").not_to match_against(String)
+      end
+
+      context "when given two 0-arg lambdas" do
+        it 'returns true when given the same lambda' do
+          k = lambda { 3 }
+          expect(k).to match_against(k)
+        end
+
+        it 'returns false when given different lambdas' do
+          expect(lambda { 3 }).not_to match_against(lambda { 4 })
+        end
+      end
+
+      context "when given an object whose implementation of `==` raises an ArgumentError" do
+        it 'surfaces the error' do
+          klass = Class.new do
+            attr_accessor :foo
+            def ==(other)
+              other.foo == foo
+            end
+          end
+          instance = klass.new
+
+          other = Object.new
+          def other.foo(arg); end
+
+          expect { instance == other }.to raise_error(ArgumentError)
+          expect { FuzzyMatcher.values_match?(other, instance) }.to raise_error(ArgumentError)
+        end
+      end
+
+      it "does not match a struct against an array" do
+        struct = Struct.new(:foo, :bar).new("first", 2)
+        expect(["first", 2]).not_to match_against(struct)
+      end
+
+      context "when given two arrays" do
+        it 'returns true if they have equal values' do
+          expect([1, 2.0]).to match_against([1.0, 2])
+        end
+
+        it 'returns false when given unequal values that do not provide match logic' do
+          expect([1, 2.0]).not_to match_against([1.1, 2])
+        end
+
+        it 'does the fuzzy matching on the individual elements' do
+          expect([String, Fixnum]).to match_against(["a", 2])
+          expect([String, Fixnum]).not_to match_against([2, "a"])
+        end
+
+        it 'returns false if they have a different number of elements' do
+          expect([String, Fixnum]).not_to match_against(['a', 2, nil])
+        end
+
+        it 'supports arbitrary nested arrays' do
+          a1 = [
+            [String, Fixnum, [be_within(0.1).of(2)]],
+            3, [[[ /foo/ ]]]
+          ]
+
+          a2 = [
+            ["a", 1, [2.05]],
+            3, [[[ "foobar" ]]]
+          ]
+
+          expect(a1).to match_against(a2)
+          a2[0][2][0] += 1
+          expect(a1).not_to match_against(a2)
+        end
+      end
+
+      it 'can match an array an arbitrary enumerable' do
+        my_enum = Class.new do
+          include Enumerable
+
+          def each
+            yield 1; yield "foo"
+          end
+        end.new
+
+        expect([Fixnum, String]).to match_against(my_enum)
+        expect([String, Fixnum]).not_to match_against(my_enum)
+      end
+
+      it 'does not match an empty hash against an empty array or vice-versa' do
+        expect({}).not_to match_against([])
+        expect([]).not_to match_against({})
+      end
+
+      context 'when given two hashes' do
+        it 'returns true when their keys and values are equal' do
+          expect(:a => 5, :b => 2.0).to match_against(:a => 5.0, :b => 2)
+        end
+
+        it 'returns false when given unequal values that do not provide match logic' do
+          expect(:a => 5).not_to match_against(:a => 5.1)
+        end
+
+        it 'does the fuzzy matching on the individual values' do
+          expect(:a => String, :b => /bar/).to match_against(:a => "foo", :b => "barn")
+          expect(:a => String, :b => /bar/).not_to match_against(:a => "foo", :b => "brn")
+        end
+
+        it 'returns false if the expected hash has nil values that are not in the actual hash' do
+          expect(:a => 'b', :b => nil).not_to match_against(:a => "b")
+        end
+
+        it 'returns false if actual hash has extra entries' do
+          expect(:a => 'b').not_to match_against(:a => "b", :b => nil)
+        end
+
+        it 'does not fuzzy match on keys' do
+          expect(/foo/ => 1).not_to match_against("foo" => 1)
+        end
+
+        it 'supports arbitrary nested hashes' do
+          h1 = {
+            :a => {
+              :b => [String, Fixnum],
+              :c => { :d => be_within(0.1).of(2) }
+            }
+          }
+
+          h2 = {
+            :a => {
+              :b => ["foo", 5],
+              :c => { :d => 2.05 }
+            }
+          }
+
+          expect(h1).to match_against(h2)
+          h2[:a][:c][:d] += 1
+          expect(h1).not_to match_against(h2)
+        end
+      end
+    end
+  end
+end
+
diff --git a/rspec-support/spec/rspec/support/matcher_definition_spec.rb b/rspec-support/spec/rspec/support/matcher_definition_spec.rb
new file mode 100644
index 0000000..59ab765
--- /dev/null
+++ b/rspec-support/spec/rspec/support/matcher_definition_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+
+module RSpec
+  module Support
+    RSpec.describe "matcher definitions" do
+      RSpec::Matchers.define :fake_matcher do |expected|
+        match { |actual| expected == actual }
+        description { :fake_matcher }
+      end
+
+      RSpec::Matchers.define :matcher_with_no_description do
+        match { true }
+        undef description
+      end
+
+      describe ".rspec_description_for_object" do
+        it "returns the object for a non matcher object" do
+          o = Object.new
+          expect(RSpec::Support.rspec_description_for_object(o)).to be o
+        end
+
+        it "returns the object's description for a matcher object that has a description" do
+          expect(RSpec::Support.rspec_description_for_object(fake_matcher(nil))).to eq :fake_matcher
+        end
+
+        it "returns the object for a matcher that does not have a description" do
+          matcher = matcher_with_no_description
+
+          expect(matcher_with_no_description).not_to respond_to(:description)
+          expect(RSpec::Support.is_a_matcher?(matcher_with_no_description)).to eq true
+
+          expect(RSpec::Support.rspec_description_for_object(matcher)).to be matcher
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/method_signature_verifier_spec.rb b/rspec-support/spec/rspec/support/method_signature_verifier_spec.rb
new file mode 100644
index 0000000..bcf7edd
--- /dev/null
+++ b/rspec-support/spec/rspec/support/method_signature_verifier_spec.rb
@@ -0,0 +1,381 @@
+require 'rspec/support'
+require 'rspec/support/method_signature_verifier'
+
+module RSpec
+  module Support
+    describe 'verifying methods' do
+      let(:signature) { MethodSignature.new(test_method) }
+
+      def valid_non_kw_args?(arity)
+        described_class.new(signature, [nil] * arity).valid?
+      end
+
+      def valid?(*args)
+        described_class.new(signature, args).valid?
+      end
+
+      def error_description
+        described_class.new(signature, []).error_message[/Expected (.*),/, 1]
+      end
+
+      def error_for(*args)
+        described_class.new(signature, args).error_message
+      end
+
+      def signature_description
+        signature.description
+      end
+
+      shared_context 'a method verifier' do
+        describe 'with a method with arguments' do
+          def arity_two(x, y); end
+
+          let(:test_method) { method(:arity_two) }
+
+          it 'covers only the exact arity' do
+            expect(valid_non_kw_args?(1)).to eq(false)
+            expect(valid_non_kw_args?(2)).to eq(true)
+            expect(valid_non_kw_args?(3)).to eq(false)
+          end
+
+          it "allows matchers to be passed as arguments" do
+            expect(valid?(anything, anything)).to eq(true)
+          end
+
+          it 'does not treat a last-arg hash as kw args' do
+            expect(valid?(1, {})).to eq(true)
+          end
+
+          it 'describes the arity precisely' do
+            expect(error_description).to eq("2")
+          end
+
+          it 'mentions only the arity in the description' do
+            expect(signature_description).to eq("arity of 2")
+          end
+
+          it 'indicates it has no optional kw args' do
+            expect(signature.optional_kw_args).to eq([])
+          end
+
+          it 'indicates it has no required kw args' do
+            expect(signature.required_kw_args).to eq([])
+          end
+        end
+
+        describe 'a method with splat arguments' do
+          def arity_splat(_, *); end
+
+          let(:test_method) { method(:arity_splat) }
+
+          it 'covers a range from the lower bound upwards' do
+            expect(valid_non_kw_args?(0)).to eq(false)
+            expect(valid_non_kw_args?(1)).to eq(true)
+            expect(valid_non_kw_args?(2)).to eq(true)
+            expect(valid_non_kw_args?(3)).to eq(true)
+          end
+
+          it 'describes the arity with no upper bound' do
+            expect(error_description).to eq("1 or more")
+          end
+
+          it 'mentions only the arity in the description' do
+            expect(signature_description).to eq("arity of 1 or more")
+          end
+        end
+
+        describe 'a method with optional arguments' do
+          def arity_optional(x, y, z = 1); end
+
+          let(:test_method) { method(:arity_optional) }
+
+          it 'covers a range from min to max possible arguments' do
+            expect(valid_non_kw_args?(1)).to eq(false)
+            expect(valid_non_kw_args?(2)).to eq(true)
+            expect(valid_non_kw_args?(3)).to eq(true)
+
+            if RubyFeatures.optional_and_splat_args_supported?
+              expect(valid_non_kw_args?(4)).to eq(false)
+            else
+              expect(valid_non_kw_args?(4)).to eq(true)
+            end
+          end
+
+          if RubyFeatures.optional_and_splat_args_supported?
+            it 'describes the arity as a range' do
+              expect(error_description).to eq("2 to 3")
+            end
+          else
+            it 'describes the arity with no upper bound' do
+              expect(error_description).to eq("2 or more")
+            end
+          end
+        end
+
+        if RubyFeatures.kw_args_supported?
+          describe 'a method with optional keyword arguments' do
+            eval <<-RUBY
+              def arity_kw(x, y:1, z:2); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw) }
+
+            it 'does not require any of the arguments' do
+              expect(valid?(nil)).to eq(true)
+              expect(valid?(nil, nil)).to eq(false)
+            end
+
+            it 'does not allow an invalid keyword arguments' do
+              expect(valid?(nil, :a => 1)).to eq(false)
+            end
+
+            it 'mentions the invalid keyword args in the error', :pending => RUBY_ENGINE == 'jruby' do
+              expect(error_for(nil, :a => 0, :b => 1)).to \
+                eq("Invalid keyword arguments provided: a, b")
+            end
+
+            it 'describes invalid arity precisely' do
+              expect(error_for()).to \
+                eq("Wrong number of arguments. Expected 1, got 0.")
+            end
+
+            it 'does not blow up when given a BasicObject as the last arg' do
+              expect(valid?(BasicObject.new)).to eq(true)
+            end
+
+            it 'does not mutate the provided args array' do
+              args = [nil, { :y => 1 }]
+              described_class.new(signature, args).valid?
+              expect(args).to eq([nil, { :y => 1 }])
+            end
+
+            it 'mentions the arity and optional kw args in the description', :pending => RUBY_ENGINE == 'jruby' do
+              expect(signature_description).to eq("arity of 1 and optional keyword args (:y, :z)")
+            end
+
+            it "indicates the optional keyword args" do
+              expect(signature.optional_kw_args).to contain_exactly(:y, :z)
+            end
+
+            it "indicates it has no required keyword args" do
+              expect(signature.required_kw_args).to eq([])
+            end
+          end
+        end
+
+        if RubyFeatures.required_kw_args_supported?
+          describe 'a method with required keyword arguments' do
+            eval <<-RUBY
+              def arity_required_kw(x, y:, z:, a: 'default'); end
+            RUBY
+
+            let(:test_method) { method(:arity_required_kw) }
+
+            it 'returns false unless all required keywords args are present' do
+              expect(valid?(nil, :a => 0, :y => 1, :z => 2)).to eq(true)
+              expect(valid?(nil, :a => 0, :y => 1)).to eq(false)
+              expect(valid?(nil, nil, :a => 0, :y => 1, :z => 2)).to eq(false)
+              expect(valid?(nil, nil)).to eq(false)
+            end
+
+            it 'mentions the missing required keyword args in the error' do
+              expect(error_for(nil, :a => 0)).to \
+                eq("Missing required keyword arguments: y, z")
+            end
+
+            it 'is described precisely when arity is wrong' do
+              expect(error_for(nil, nil, :z => 0, :y => 1)).to \
+                eq("Wrong number of arguments. Expected 1, got 2.")
+            end
+
+            it 'mentions the arity, optional kw args and required kw args in the description' do
+              expect(signature_description).to \
+                eq("arity of 1 and optional keyword args (:a) and required keyword args (:y, :z)")
+            end
+
+            it "indicates the optional keyword args" do
+              expect(signature.optional_kw_args).to contain_exactly(:a)
+            end
+
+            it "indicates the required keyword args" do
+              expect(signature.required_kw_args).to contain_exactly(:y, :z)
+            end
+          end
+
+          describe 'a method with required keyword arguments and a splat' do
+            eval <<-RUBY
+              def arity_required_kw_splat(w, *x, y:, z:, a: 'default'); end
+            RUBY
+
+            let(:test_method) { method(:arity_required_kw_splat) }
+
+            it 'returns false unless all required keywords args are present' do
+              expect(valid?(nil, :a => 0, :y => 1, :z => 2)).to eq(true)
+              expect(valid?(nil, :a => 0, :y => 1)).to eq(false)
+              expect(valid?(nil, nil, :a => 0, :y => 1, :z => 2)).to eq(true)
+              expect(valid?(nil, nil, nil)).to eq(false)
+              expect(valid?).to eq(false)
+            end
+
+            it 'mentions missing required keyword args in the error' do
+              expect(error_for(nil, :y => 1)).to \
+                eq("Missing required keyword arguments: z")
+            end
+
+            it 'mentions the arity, optional kw args and required kw args in the description' do
+              expect(signature_description).to \
+                eq("arity of 1 or more and optional keyword args (:a) and required keyword args (:y, :z)")
+            end
+          end
+
+          describe 'a method with required keyword arguments and a keyword arg splat' do
+            eval <<-RUBY
+              def arity_kw_arg_splat(x:, **rest); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw_arg_splat) }
+
+            it 'allows extra undeclared keyword args' do
+              expect(valid?(:x => 1)).to eq(true)
+              expect(valid?(:x => 1, :y => 2)).to eq(true)
+            end
+
+            it 'mentions missing required keyword args in the error' do
+              expect(error_for(:y => 1)).to \
+                eq("Missing required keyword arguments: x")
+            end
+
+            it 'mentions the required kw args and keyword splat in the description' do
+              expect(signature_description).to \
+                eq("required keyword args (:x) and any additional keyword args")
+            end
+          end
+
+          describe 'a method with a required arg and a keyword arg splat' do
+            eval <<-RUBY
+              def arity_kw_arg_splat(x, **rest); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw_arg_splat) }
+
+            it 'allows a single arg and any number of keyword args' do
+              expect(valid?(nil)).to eq(true)
+              expect(valid?(nil, :x => 1)).to eq(true)
+              expect(valid?(nil, :x => 1, :y => 2)).to eq(true)
+              expect(valid?(:x => 1)).to eq(true)
+
+              expect(valid?).to eq(false)
+              expect(valid?(nil, nil)).to eq(false)
+              expect(valid?(nil, nil, :x => 1)).to eq(false)
+            end
+
+            it 'describes the arity precisely' do
+              expect(error_for()).to \
+                eq("Wrong number of arguments. Expected 1, got 0.")
+            end
+
+            it 'mentions the required kw args and keyword splat in the description' do
+              expect(signature_description).to \
+                eq("arity of 1 and any additional keyword args")
+            end
+          end
+        end
+
+        describe 'a method with a block' do
+          def arity_block(_, &block); end
+
+          let(:test_method) { method(:arity_block) }
+
+          it 'does not count the block as a parameter' do
+            expect(valid_non_kw_args?(1)).to eq(true)
+            expect(valid_non_kw_args?(2)).to eq(false)
+          end
+
+          it 'describes the arity precisely' do
+            expect(error_description).to eq("1")
+          end
+        end
+      end
+
+      let(:fake_matcher) { Object.new }
+      let(:fake_matcher_def) { lambda {|x| fake_matcher == x }}
+
+      before do
+        RSpec::Support.register_matcher_definition(&fake_matcher_def)
+      end
+
+      after do
+        RSpec::Support.deregister_matcher_definition(&fake_matcher_def)
+      end
+
+
+      describe StrictSignatureVerifier do
+        it_behaves_like 'a method verifier'
+
+        if RubyFeatures.kw_args_supported?
+          describe 'providing a matcher for optional keyword arguments' do
+            eval <<-RUBY
+              def arity_kw(x, y:1); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw) }
+
+            it 'is not allowed' do
+              expect(valid?(nil, fake_matcher)).to eq(false)
+            end
+          end
+        end
+
+        if RubyFeatures.required_kw_args_supported?
+          describe 'providing a matcher for required keyword arguments' do
+            eval <<-RUBY
+              def arity_kw_required(x, y:); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw_required) }
+
+            it 'is not allowed' do
+              expect(valid?(nil, fake_matcher)).to eq(false)
+            end
+          end
+        end
+      end
+
+      describe LooseSignatureVerifier do
+        it_behaves_like 'a method verifier'
+
+        if RubyFeatures.kw_args_supported?
+          describe 'for optional keyword arguments' do
+            eval <<-RUBY
+              def arity_kw(x, y:1, z:2); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw) }
+
+            it 'allows a matcher' do
+              expect(valid?(nil, fake_matcher)).to eq(true)
+            end
+
+            it 'allows a matcher only for positional arguments' do
+              expect(valid?(fake_matcher)).to eq(true)
+            end
+          end
+        end
+
+        if RubyFeatures.required_kw_args_supported?
+          describe 'providing a matcher for required keyword arguments' do
+            eval <<-RUBY
+              def arity_kw_required(x, y:); end
+            RUBY
+
+            let(:test_method) { method(:arity_kw_required) }
+
+            it 'is allowed' do
+              expect(valid?(nil, fake_matcher)).to eq(true)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/recursive_const_methods_spec.rb b/rspec-support/spec/rspec/support/recursive_const_methods_spec.rb
new file mode 100644
index 0000000..a7ae576
--- /dev/null
+++ b/rspec-support/spec/rspec/support/recursive_const_methods_spec.rb
@@ -0,0 +1,49 @@
+require 'rspec/support/recursive_const_methods'
+
+module RSpec
+  module Support
+    describe RecursiveConstMethods do
+      include described_class
+
+      module Foo
+        class Parent
+          UNDETECTED = 'Not seen when looking up constants in Bar'
+        end
+
+        class Bar < Parent
+          VAL = 10
+        end
+      end
+
+      describe '#recursive_const_defined?' do
+        it 'finds constants' do
+          const, _ = recursive_const_defined?('::RSpec::Support::Foo::Bar::VAL')
+
+          expect(const).to eq(10)
+        end
+
+        it 'returns the fully qualified name of the constant' do
+          _, name = recursive_const_defined?('::RSpec::Support::Foo::Bar::VAL')
+
+          expect(name).to eq('RSpec::Support::Foo::Bar::VAL')
+        end
+
+        it 'does not find constants in ancestors' do
+          expect(recursive_const_defined?('::RSpec::Support::Foo::Bar::UNDETECTED')).to be_falsy
+        end
+      end
+
+      describe '#recursive_const_get' do
+        it 'gets constants' do
+          expect(recursive_const_get('::RSpec::Support::Foo::Bar::VAL')).to eq(10)
+        end
+
+        it 'does not get constants in ancestors' do
+          expect do
+            recursive_const_get('::RSpec::Support::Foo::Bar::UNDETECTED')
+          end.to raise_error(NameError)
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/ruby_features_spec.rb b/rspec-support/spec/rspec/support/ruby_features_spec.rb
new file mode 100644
index 0000000..df0dcde
--- /dev/null
+++ b/rspec-support/spec/rspec/support/ruby_features_spec.rb
@@ -0,0 +1,82 @@
+require 'rspec/support/ruby_features'
+
+module RSpec
+  module Support
+    describe OS do
+
+      describe ".windows?" do
+        %w[cygwin mswin mingw bccwin wince emx].each do |fragment|
+          it "returns true when host os is #{fragment}" do
+            stub_const("RbConfig::CONFIG", 'host_os' => fragment)
+            expect(OS).to be_windows
+          end
+        end
+
+        %w[darwin linux].each do |fragment|
+          it "returns false when host os is #{fragment}" do
+            stub_const("RbConfig::CONFIG", 'host_os' => fragment)
+            expect(OS).to_not be_windows
+          end
+        end
+      end
+
+      describe ".windows_file_path?" do
+        it "returns true when the file alt seperator is a colon" do
+          stub_const("File::ALT_SEPARATOR", "\\") unless OS.windows?
+          expect(OS).to be_windows_file_path
+        end
+
+        it "returns false when file alt seperator is not present" do
+          stub_const("File::ALT_SEPARATOR", nil) if OS.windows?
+          expect(OS).to_not be_windows_file_path
+        end
+      end
+    end
+
+    describe Ruby do
+      specify "jruby? reflects the state of RUBY_PLATFORM" do
+        stub_const("RUBY_PLATFORM", "java")
+        expect(Ruby).to be_jruby
+        stub_const("RUBY_PLATFORM", "")
+        expect(Ruby).to_not be_jruby
+      end
+
+      specify "rbx? reflects the state of RUBY_ENGINE" do
+        stub_const("RUBY_ENGINE", "rbx")
+        expect(Ruby).to be_rbx
+        hide_const("RUBY_ENGINE")
+        expect(Ruby).to_not be_rbx
+      end
+
+      specify "rbx? reflects the state of RUBY_ENGINE" do
+        hide_const("RUBY_ENGINE")
+        expect(Ruby).to be_mri
+        stub_const("RUBY_ENGINE", "ruby")
+        expect(Ruby).to be_mri
+        stub_const("RUBY_ENGINE", "rbx")
+        expect(Ruby).to_not be_mri
+      end
+    end
+
+    describe RubyFeatures do
+      specify "#kw_args_supported? exists" do
+        RubyFeatures.kw_args_supported?
+      end
+
+      specify "#required_kw_args_supported? exists" do
+        RubyFeatures.required_kw_args_supported?
+      end
+
+      specify "#supports_rebinding_module_methods? exists" do
+        RubyFeatures.supports_rebinding_module_methods?
+      end
+
+      specify "#caller_locations_supported? exists" do
+        RubyFeatures.caller_locations_supported?
+        if Ruby.mri?
+          expect(RubyFeatures.caller_locations_supported?).to eq(RUBY_VERSION >= '2.0.0')
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/spec/in_sub_process_spec.rb b/rspec-support/spec/rspec/support/spec/in_sub_process_spec.rb
new file mode 100644
index 0000000..c88804d
--- /dev/null
+++ b/rspec-support/spec/rspec/support/spec/in_sub_process_spec.rb
@@ -0,0 +1,48 @@
+require 'rspec/support/spec/in_sub_process'
+require 'tempfile'
+
+describe 'isolating code to a sub process' do
+  include RSpec::Support::InSubProcess
+
+  it 'isolates the block from the main process' do
+    in_sub_process do
+      module NotIsolated
+      end
+      expect(defined? NotIsolated).to eq "constant"
+    end
+    expect(defined? NotIsolated).to be_nil
+  end
+
+  if Process.respond_to?(:fork) && !(RUBY_PLATFORM == 'java' && RUBY_VERSION == '1.8.7')
+
+    it 'captures and reraises errors to the main process' do
+      expect {
+        in_sub_process { raise "An Internal Error" }
+      }.to raise_error "An Internal Error"
+    end
+
+    it 'captures and reraises test failures' do
+      expect {
+        in_sub_process { expect(true).to be false }
+      }.to raise_error(/expected false/)
+    end
+
+    it 'fails if the sub process generates warnings' do
+      expect {
+        in_sub_process do
+          # Redirect stderr so we don't get "boom" in our test suite output
+          $stderr.reopen(Tempfile.new("stderr"))
+
+          warn "boom"
+        end
+      }.to raise_error(RuntimeError, a_string_including("Warnings", "boom"))
+    end
+
+  else
+
+    it 'pends the block' do
+      expect { in_sub_process { true } }.to raise_error(/This spec requires forking to work properly/)
+    end
+
+  end
+end
diff --git a/rspec-support/spec/rspec/support/spec/prevent_load_time_warnings_spec.rb b/rspec-support/spec/rspec/support/spec/prevent_load_time_warnings_spec.rb
new file mode 100644
index 0000000..70f3b05
--- /dev/null
+++ b/rspec-support/spec/rspec/support/spec/prevent_load_time_warnings_spec.rb
@@ -0,0 +1,10 @@
+require 'rspec/support/spec/prevent_load_time_warnings'
+
+RSpec.describe RSpec::Support::WarningsPrevention do
+  include described_class
+
+  it 'finds all the files for the named lib and extracts the portion to require' do
+    files = files_to_require_for("rspec-support", "lib")
+    expect(files).to include("rspec/support", "rspec/support/spec/prevent_load_time_warnings")
+  end
+end
diff --git a/rspec-support/spec/rspec/support/spec/shell_out_spec.rb b/rspec-support/spec/rspec/support/spec/shell_out_spec.rb
new file mode 100644
index 0000000..920ae4f
--- /dev/null
+++ b/rspec-support/spec/rspec/support/spec/shell_out_spec.rb
@@ -0,0 +1,44 @@
+require 'rspec/support/spec/shell_out'
+
+RSpec.describe RSpec::Support::ShellOut, :slow do
+  include described_class
+
+  it 'shells out and returns stdout and stderr' do
+    stdout, stderr, _ = shell_out("ruby", "-e", "$stdout.print 'yes'; $stderr.print 'no'")
+    expect(stdout).to eq("yes")
+    expect(stderr).to eq("no")
+  end
+
+  it 'returns the exit status as the third argument' do
+    _, _, good_status = shell_out("ruby", "-e", '3 + 3')
+    expect(good_status.exitstatus).to eq(0)
+
+    unless RUBY_VERSION.to_f < 1.9 # except 1.8...
+      _, _, bad_status = shell_out("ruby", "-e", 'boom')
+      expect(bad_status.exitstatus).to eq(1)
+    end
+  end
+
+  it 'can shell out to ruby with the current load path' do
+    out, err, status = run_ruby_with_current_load_path('puts $LOAD_PATH.sort.join("\n")')
+    expect(err).to eq("")
+    expect(out).to include(*$LOAD_PATH.first(10))
+    expect(status.exitstatus).to eq(0)
+  end
+
+  it 'passes along the provided ruby flags' do
+    out, err, status = run_ruby_with_current_load_path('puts "version"', '-v')
+    expect(out).to include('version', RUBY_DESCRIPTION)
+    expect(err).to eq('')
+    expect(status.exitstatus).to eq(0)
+  end
+
+  it 'filters out the annoying output issued by `ruby -w` when the GC ENV vars are set' do
+    with_env 'RUBY_GC_HEAP_FREE_SLOTS' => '10001', 'RUBY_GC_MALLOC_LIMIT' => '16777217', 'RUBY_FREE_MIN' => '10001' do
+      out, err, status = run_ruby_with_current_load_path('', '-w')
+      expect(out).to eq('')
+      expect(err).to eq('')
+      expect(status.exitstatus).to eq(0)
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/spec/stderr_splitter_spec.rb b/rspec-support/spec/rspec/support/spec/stderr_splitter_spec.rb
new file mode 100644
index 0000000..4eea751
--- /dev/null
+++ b/rspec-support/spec/rspec/support/spec/stderr_splitter_spec.rb
@@ -0,0 +1,92 @@
+require 'rspec/support/spec/stderr_splitter'
+require 'tempfile'
+require 'rspec/support/spec/in_sub_process'
+
+describe 'RSpec::Support::StdErrSplitter' do
+  include RSpec::Support::InSubProcess
+
+  let(:splitter) { RSpec::Support::StdErrSplitter.new stderr }
+  let(:stderr)   { STDERR }
+
+  before do
+    allow(stderr).to receive(:write)
+  end
+
+  around do |example|
+    original = $stderr
+    $stderr = splitter
+
+    example.run
+
+    $stderr = original
+  end
+
+  it 'conforms to the stderr interface' do
+    stderr_methods = stderr.methods
+
+    # On 2.2, there's a weird issue where stderr sometimes responds to `birthtime` and sometimes doesn't...
+    stderr_methods -= [:birthtime] if RUBY_VERSION =~ /^2\.2/
+
+    # No idea why, but on our AppVeyor windows builds it doesn't respond to these...
+    stderr_methods -= [:close_on_exec?, :close_on_exec=] if RSpec::Support::OS.windows?
+
+    expect(splitter).to respond_to(*stderr_methods)
+  end
+
+  it 'acknowledges its own interface' do
+    expect(splitter).to respond_to :==, :write, :has_output?, :reset!, :verify_example!, :output
+  end
+
+  it 'supports methods that stderr supports but StringIO does not' do
+    expect(StringIO.new).not_to respond_to(:stat)
+    expect(splitter.stat).to be_a(File::Stat)
+  end
+
+  it 'supports #to_io' do
+    expect(splitter.to_io).to be(stderr.to_io)
+  end
+
+  it 'behaves like stderr' do
+    splitter.write 'a warning'
+    expect(stderr).to have_received(:write)
+  end
+
+  it 'pretends to be stderr' do
+    expect(splitter).to eq stderr
+  end
+
+  it 'resets when reopened' do
+    in_sub_process(false) do
+      warn 'a warning'
+      allow(stderr).to receive(:write).and_call_original
+
+      Tempfile.open('stderr') do |file|
+        splitter.reopen(file)
+        expect { splitter.verify_example! self }.not_to raise_error
+      end
+    end
+  end
+
+  it 'tracks when output to' do
+    splitter.write 'a warning'
+    expect(splitter).to have_output
+  end
+
+  it 'will ignore examples without a warning' do
+    splitter.verify_example! self
+  end
+
+  it 'will ignore examples after a reset a warning' do
+    warn 'a warning'
+    splitter.reset!
+    splitter.verify_example! self
+  end
+
+  unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+    it 'will fail an example which generates a warning' do
+      true unless @undefined
+      expect { splitter.verify_example! self }.to raise_error(/Warnings were generated:/)
+    end
+  end
+
+end
diff --git a/rspec-support/spec/rspec/support/spec/with_isolated_std_err_spec.rb b/rspec-support/spec/rspec/support/spec/with_isolated_std_err_spec.rb
new file mode 100644
index 0000000..62ab0df
--- /dev/null
+++ b/rspec-support/spec/rspec/support/spec/with_isolated_std_err_spec.rb
@@ -0,0 +1,21 @@
+require 'rspec/support/spec'
+
+describe 'isolating a spec from the stderr splitter' do
+  include RSpec::Support::WithIsolatedStdErr
+
+  it 'allows a spec to output a warning' do
+    with_isolated_stderr do
+      $stderr.puts "Imma gonna warn you"
+    end
+  end
+
+  it 'resets $stderr to its original value even if an error is raised' do
+    orig_stderr = $stderr
+
+    expect {
+      with_isolated_stderr { raise "boom" }
+    }.to raise_error("boom")
+
+    expect($stderr).to be(orig_stderr)
+  end
+end
diff --git a/rspec-support/spec/rspec/support/version_checker_spec.rb b/rspec-support/spec/rspec/support/version_checker_spec.rb
new file mode 100644
index 0000000..40ab17c
--- /dev/null
+++ b/rspec-support/spec/rspec/support/version_checker_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+require 'rspec/support/version_checker'
+
+module RSpec::Support
+  describe VersionChecker do
+    def check_version(*args)
+      VersionChecker.new(*args).check_version!
+    end
+
+    it 'raises an error if the major version is too low' do
+      expect { check_version('some_gem', '0.7.3', '1.0.0') }.to raise_error(LibraryVersionTooLowError)
+    end
+
+    it 'raises an error if the minor version is too low' do
+      expect { check_version('some_gem', '1.0.99', '1.1.3') }.to raise_error(LibraryVersionTooLowError)
+    end
+
+    it 'raises an error if the patch version is too low' do
+      expect { check_version('some_gem', '1.0.8', '1.0.10') }.to raise_error(LibraryVersionTooLowError)
+    end
+
+    it 'does not raise an error when the version is above the min version' do
+      check_version('some_gem', '2.0.0', '1.0.0')
+      check_version('some_gem', '1.2.0', '1.1.0')
+      check_version('some_gem', '1.1.3', '1.1.1')
+      check_version('some_gem', '1.1.3', '1.1.3')
+    end
+  end
+end
diff --git a/rspec-support/spec/rspec/support/warnings_spec.rb b/rspec-support/spec/rspec/support/warnings_spec.rb
new file mode 100644
index 0000000..5972819
--- /dev/null
+++ b/rspec-support/spec/rspec/support/warnings_spec.rb
@@ -0,0 +1,66 @@
+require "spec_helper"
+require "rspec/support/warnings"
+require 'rspec/support/spec/shell_out'
+
+describe "rspec warnings and deprecations" do
+  include RSpec::Support::ShellOut
+  let(:warning_object) do
+    Object.new.tap { |o| o.extend(RSpec::Support::Warnings) }
+  end
+
+  it 'works when required in isolation' do
+    out, err, status = run_ruby_with_current_load_path("RSpec.deprecate('foo')", "-rrspec/support/warnings")
+    expect(out).to eq("")
+    expect(err).to start_with("DEPRECATION: foo is deprecated")
+    expect(status.exitstatus).to eq(0)
+  end
+
+  context "when rspec-core is not available" do
+    shared_examples "falling back to Kernel.warn" do |args|
+      let(:method_name) { args.fetch(:method_name) }
+
+      it 'falls back to warning with a plain message' do
+        expect(::Kernel).to receive(:warn).with(/message/)
+        warning_object.send(method_name, 'message')
+      end
+
+      it "handles being passed options" do
+        expect(::Kernel).to receive(:warn).with(/message/)
+        warning_object.send(method_name, "this is the message", :type => :test)
+      end
+    end
+
+    it_behaves_like 'falling back to Kernel.warn', :method_name => :deprecate
+    it_behaves_like 'falling back to Kernel.warn', :method_name => :warn_deprecation
+  end
+
+  shared_examples "warning helper" do |helper|
+    it 'warns with the message text' do
+      expect(::Kernel).to receive(:warn).with(/Message/)
+      warning_object.send(helper, 'Message')
+    end
+
+    it 'sets the calling line' do
+      expect(::Kernel).to receive(:warn).with(/#{__FILE__}:#{__LINE__+1}/)
+      warning_object.send(helper, 'Message')
+    end
+
+    it 'optionally sets the replacement' do
+      expect(::Kernel).to receive(:warn).with(/Use Replacement instead./)
+      warning_object.send(helper, 'Message', :replacement => 'Replacement')
+    end
+  end
+
+  describe "#warning" do
+    it 'prepends WARNING:' do
+      expect(::Kernel).to receive(:warn).with(/WARNING: Message\./)
+      warning_object.warning 'Message'
+    end
+
+    it_should_behave_like 'warning helper', :warning
+  end
+
+  describe "#warn_with message, options" do
+    it_should_behave_like 'warning helper', :warn_with
+  end
+end
diff --git a/rspec-support/spec/rspec/support_spec.rb b/rspec-support/spec/rspec/support_spec.rb
new file mode 100644
index 0000000..f051e11
--- /dev/null
+++ b/rspec-support/spec/rspec/support_spec.rb
@@ -0,0 +1,119 @@
+require 'rspec/support'
+require 'rspec/support/spec/prevent_load_time_warnings'
+
+module RSpec
+  describe Support do
+    extend Support::RubyFeatures
+
+    it_behaves_like "a library that issues no warnings when loaded", "rspec-support",
+      # Define methods that some of our rspec/support/spec files use at load time.
+      "module RSpec; def self.configure; end; def self.shared_context(*); end; def self.shared_examples_for(*); end; end",
+      'require "rspec/support"'
+
+    describe '.method_handle_for(object, method_name)' do
+      untampered_class = Class.new do
+        def foo
+          :bar
+        end
+      end
+
+      http_request_class = Struct.new(:method, :uri)
+
+      proxy_class = Struct.new(:original) do
+        undef :=~, :method
+        def method_missing(name, *args, &block)
+          original.__send__(name, *args, &block)
+        end
+      end
+
+      it 'fetches method definitions for vanilla objects' do
+        object = untampered_class.new
+        expect(Support.method_handle_for(object, :foo).call).to eq :bar
+      end
+
+      it 'fetches method definitions for objects with method redefined' do
+        request = http_request_class.new(:get, "http://foo.com/")
+        expect(Support.method_handle_for(request, :uri).call).to eq "http://foo.com/"
+      end
+
+      it 'fetches method definitions for proxy objects' do
+        object = proxy_class.new([])
+        expect(Support.method_handle_for(object, :=~)).to be_a Method
+      end
+
+      it 'fetches method definitions for proxy objects' do
+        object = proxy_class.new([])
+        expect(Support.method_handle_for(object, :=~)).to be_a Method
+      end
+
+      it 'fails with `NameError` when an undefined method is fetched ' +
+         'from an object that has overriden `method` to raise an Exception' do
+        object = double
+        allow(object).to receive(:method).and_raise(Exception)
+        expect {
+          Support.method_handle_for(object, :some_undefined_method)
+        }.to raise_error(NameError)
+      end
+
+      it 'fails with `NameError` when a method is fetched from an object ' +
+         'that has overriden `method` to not return a method' do
+        object = proxy_class.new(double(:method => :baz))
+        expect {
+          Support.method_handle_for(object, :=~)
+        }.to raise_error(NameError)
+      end
+
+      context "for a BasicObject subclass", :if => RUBY_VERSION.to_f > 1.8 do
+        let(:basic_class) do
+          Class.new(BasicObject) do
+            def foo
+              :bar
+            end
+          end
+        end
+
+        let(:basic_class_with_method_override) do
+          Class.new(basic_class) do
+            def method
+              :method
+            end
+          end
+        end
+
+        let(:basic_class_with_kernel) do
+          Class.new(basic_class) do
+            include ::Kernel
+          end
+        end
+
+        let(:basic_class_with_proxying) do
+          Class.new(BasicObject) do
+            def method_missing(name, *args, &block)
+              "foo".__send__(name, *args, &block)
+            end
+          end
+        end
+
+        it 'still works', :if => supports_rebinding_module_methods? do
+          object = basic_class.new
+          expect(Support.method_handle_for(object, :foo).call).to eq :bar
+        end
+
+        it 'works when `method` has been overriden', :if => supports_rebinding_module_methods? do
+          object = basic_class_with_method_override.new
+          expect(Support.method_handle_for(object, :foo).call).to eq :bar
+        end
+
+        it 'allows `method` to be proxied', :unless => supports_rebinding_module_methods? do
+          object = basic_class_with_proxying.new
+          expect(Support.method_handle_for(object, :reverse).call).to eq "oof"
+        end
+
+        it 'still works when Kernel has been mixed in' do
+          object = basic_class_with_kernel.new
+          expect(Support.method_handle_for(object, :foo).call).to eq :bar
+        end
+      end
+    end
+  end
+end
diff --git a/rspec-support/spec/spec_helper.rb b/rspec-support/spec/spec_helper.rb
new file mode 100644
index 0000000..c4f97db
--- /dev/null
+++ b/rspec-support/spec/spec_helper.rb
@@ -0,0 +1,2 @@
+require 'rspec/support/spec'
+RSpec::Support::Spec.setup_simplecov
diff --git a/rspec/.document b/rspec/.document
new file mode 100644
index 0000000..08e9869
--- /dev/null
+++ b/rspec/.document
@@ -0,0 +1,2 @@
+README.md
+License.txt
diff --git a/rspec/.gitignore b/rspec/.gitignore
new file mode 100644
index 0000000..050c75b
--- /dev/null
+++ b/rspec/.gitignore
@@ -0,0 +1,11 @@
+*.sw?
+.DS_Store
+coverage
+doc
+pkg
+Gemfile.lock
+.bundle
+*.rbc
+bin
+bundle
+.bundle
diff --git a/rspec/Gemfile b/rspec/Gemfile
new file mode 100644
index 0000000..f6a9153
--- /dev/null
+++ b/rspec/Gemfile
@@ -0,0 +1,7 @@
+source "https://rubygems.org"
+
+gem "rake"
+
+%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
+  gem lib, :path => File.expand_path("../../#{lib}", __FILE__)
+end
diff --git a/License.txt b/rspec/License.txt
similarity index 100%
rename from License.txt
rename to rspec/License.txt
diff --git a/README.md b/rspec/README.md
similarity index 94%
rename from README.md
rename to rspec/README.md
index 904ebe6..a0d6fc1 100644
--- a/README.md
+++ b/rspec/README.md
@@ -1,10 +1,10 @@
-# RSpec-2
+# RSpec
 
 Behaviour Driven Development for Ruby
 
 # Description
 
-rspec-2.x is a meta-gem, which depends on the rspec-core, rspec-expectations
+rspec is a meta-gem, which depends on the rspec-core, rspec-expectations
 and rspec-mocks gems. Each of these can be installed separately and actived in
 isolation with the `gem` command. Among other benefits, this allows you to use
 rspec-expectations, for example, in Test::Unit::TestCase if you happen to
diff --git a/rspec/Rakefile b/rspec/Rakefile
new file mode 100644
index 0000000..709fe1c
--- /dev/null
+++ b/rspec/Rakefile
@@ -0,0 +1,25 @@
+require "bundler"
+Bundler.setup
+Bundler::GemHelper.install_tasks
+
+require 'rake'
+require 'fileutils'
+require 'pathname'
+
+task :clobber do
+  rm_rf 'pkg'
+end
+
+task :default do
+  puts "Nothing to do for the default task"
+end
+
+task :verify_private_key_present do
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  unless File.exist?(private_key)
+    raise "Your private key is not present. This gem should not be built without that."
+  end
+end
+
+task :build => :verify_private_key_present
+
diff --git a/rspec/certs/rspec.pem b/rspec/certs/rspec.pem
new file mode 100644
index 0000000..e4c0712
--- /dev/null
+++ b/rspec/certs/rspec.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF1TCCA72gAwIBAgIJAPXjfUbCjdXUMA0GCSqGSIb3DQEBBQUAMIGAMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEO
+MAwGA1UECgwFUlNwZWMxEzARBgNVBAMMCnJzcGVjLmluZm8xJTAjBgkqhkiG9w0B
+CQEWFnJzcGVjQGdvb2dsZWdyb3Vwcy5jb20wHhcNMTQxMjIzMDkzNTIyWhcNMjQx
+MjIyMDkzNTIyWjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x
+EDAOBgNVBAcMB1NlYXR0bGUxDjAMBgNVBAoMBVJTcGVjMRMwEQYDVQQDDApyc3Bl
+Yy5pbmZvMSUwIwYJKoZIhvcNAQkBFhZyc3BlY0Bnb29nbGVncm91cHMuY29tMIIC
+IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsSmjgcHaKlD0jizRJowi2bGI
+KMOHnJoExxRNHHxH+3w9kkl95YldvDRVX495b13ZCzwRe0AyqX24wq04tp0G5Z5C
+e/w2pnNK4ol1eECPwQu+YGpepeODlZICL5gwQspe0cDifbBnHx5QySMiPpvx6bC0
+tQTox0ppDIaMhch8IPCwyoE4DQK5bpsdwnLSHTsQjUIb7IM8tUMpd/iKrJgNffwc
+6gC1TmhIlzQoB26nCNh9uK7xZjUM+sGECzvcYuImchUaIgJA/ybrlZS+m/hxzvBo
+mLnn/xNEC6Vz5HG+3TR0Gb0cSUf6XUu2s51Jk/SJi3MhCZp2gs9OUg4EVZNzQVkZ
+efLBjAZG2Mxk14JyB4/Omc+Jk0ajprINCBbUNnxzCJrYDM3J9TVWIwyUGNX/U3MO
+s3tMAT+EVgx/mZMPnBO8EULlyF51MRUp3Wy9Mnw8AYLk30UnMG5AjqgO5JNyFlA7
+Xeh3EVdWY3vMB1pkhPwlsenpcmj5gOzrd54lELOVbCGHCf48iSqeflY2Lhe0pvzK
+blXCJBDmtrebvus291rM/dHcbEfK1SVd5Wut/n131iouf6dnNCFskFygDcgBbthC
+gpEMqf80lEmhX59VUsm0Pv6OEo+ZPHBvXPiJA6DShQh9t3YtpwyA8uVDMbT/i32u
+2FUsqZbbJcCmkBrGposCAwEAAaNQME4wHQYDVR0OBBYEFPPvQ5XT0Nvuhi6k+hrW
+Vv35J+TeMB8GA1UdIwQYMBaAFPPvQ5XT0Nvuhi6k+hrWVv35J+TeMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADggIBAIqbQSWH2aAF537DKwAMB8nMFsoe24MD
+gtuQAyjTtbH+QBE4N2RdQF/sU7Y3PYR7nqdrCsYc3RxyqM5XXi7I3IYdpfe1RuxY
++pyPzVQsPPDhMlJlCrwJsADnxlpxZlAgxYSLKOan55ihscaAWA90wqRUrf/ZJM36
+8LWCPVn5teIt5aaxZWX68RMxa+AXvpbtJOBwXLkIFk3apD8CX4DhelIdw67DbkUe
+ghUd/u62qrnqBTVgditt7OoWIZjzh24/Fda5d0MxZyvLILGOrf5bN4cTbe/q9Cid
+Xrik7Upm+mu3y3yQIfrw85xybHq6iNXyYHvCdSrFfCIKrGpd/0CAdmYnJlx59Fk/
+UbD3Eyx4psBSkU+WKO0Uf+3zNI7N/nVeNIwU/Ft+l8l7/K+427656c+ZGWDO0Gt/
+BeEOSTDKP7qQ1T+JvMrBcBQo+i0cnRT10J1aoV90BhxsvWTRizIbugbaqR6Tq3bj
+Akt00cIlNSplL6DenIAKSh5kF7s0tRD0tC3bNkZmNjNGkdoGEcUODEpTB3RHKKiu
+e6k2Jg6m00z5vGFQhOnROG/QaUzMA3A3mFBe1RHFo07xd0pFeoeWL3vF69Gx9Jwp
+ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
+F3MdtaDehhjC
+-----END CERTIFICATE-----
diff --git a/rspec/certs/samphippen.asc b/rspec/certs/samphippen.asc
new file mode 100644
index 0000000..a3a0a66
--- /dev/null
+++ b/rspec/certs/samphippen.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+Comment: GPGTools - http://gpgtools.org
+
+iQIcBAABAgAGBQJUmVdPAAoJEKwl90pEDFVi6AwP/iFWdVaiWOHffXl2qZ7fi6QV
+6Dl0aPFErES9rQoJQ6oa2IOdUBlKbyi2hWeHeExXpnDf2l+PCDZU8Jy/XDdvPXCH
+jdKup+un8GWPk1X1PijYlfBpRqiJ/j5xedMiw+G/LwV4Lh1ltGBKABoKKsnoLUD3
+S1bY5636tvBxU6HkhLVutSKUFeiRuavX5rpQSlzp9rlbsdAOU0/codh81F2ENhJa
+TobfB4AhJGqVG7lrIFWzvcfyXakFMMYDPI6tIEHTXk1EaHjJyfLB7aI/4ri2vJdb
+OpHd/zrqTuIyc4Y/4+JVL/CyiNPZvPf27k8vjeIgRYvSiaXDsaysK4Ox/AqN51JL
+bZg7S39ARMI+LH/jvg+5Gb6hUyGnc+sIyceKktlze46TElZQo6QZOAO5v0EUWsH9
+Wcj27hb+iZJ9gmmE46Ns+u/r2aT596eJxIe9NatoP/1A1d89vKYU1eGTijLk3L5A
+4B+1lzofgcN3NWURu8zr6rRWLdoi39HfFRg0ETWArxgpKRpRIwK3Nkg6VlEHL+7+
+AitAONGdgQkvy3DLtzR8952GqUmOby/kxct82wOo6DIs/IWsRSW9wcaSsXgOOyjJ
+Up3Z9POr5VfFINusyXT1FkGnolb6piuiPlKiwHAr4rySUglXKd0Tx7EboB2PwQSi
+9KhkO7foz/VItBIEs+s8
+=Ggk4
+-----END PGP SIGNATURE-----
diff --git a/lib/rspec.rb b/rspec/lib/rspec.rb
similarity index 100%
rename from lib/rspec.rb
rename to rspec/lib/rspec.rb
diff --git a/lib/rspec/version.rb b/rspec/lib/rspec/version.rb
similarity index 73%
rename from lib/rspec/version.rb
rename to rspec/lib/rspec/version.rb
index f213a29..79315d3 100644
--- a/lib/rspec/version.rb
+++ b/rspec/lib/rspec/version.rb
@@ -1,5 +1,5 @@
 module RSpec # :nodoc:
   module Version # :nodoc:
-    STRING = '2.14.1'
+    STRING = '3.2.0'
   end
 end
diff --git a/rspec/rspec.gemspec b/rspec/rspec.gemspec
new file mode 100644
index 0000000..73eb6f4
--- /dev/null
+++ b/rspec/rspec.gemspec
@@ -0,0 +1,40 @@
+# -*- encoding: utf-8 -*-
+
+$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
+require "rspec/version"
+
+Gem::Specification.new do |s|
+  s.name        = "rspec"
+  s.version     = RSpec::Version::STRING
+  s.platform    = Gem::Platform::RUBY
+  s.license     = "MIT"
+  s.authors     = ["Steven Baker", "David Chelimsky", "Myron Marston"]
+  s.email       = "rspec at googlegroups.com"
+  s.homepage    = "http://github.com/rspec"
+  s.summary     = "rspec-#{RSpec::Version::STRING}"
+  s.description = "BDD for Ruby"
+
+  s.rubyforge_project  = "rspec"
+
+  s.files            = `git ls-files -- lib/*`.split("\n")
+  s.files           += ["License.txt"]
+  s.test_files       = `git ls-files -- {spec,features}/*`.split("\n")
+  s.executables      = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+  s.extra_rdoc_files = [ "README.md" ]
+  s.rdoc_options     = ["--charset=UTF-8"]
+  s.require_path     = "lib"
+
+  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
+  if File.exist?(private_key)
+    s.signing_key = private_key
+    s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
+  end
+
+  %w[core expectations mocks].each do |name|
+    if RSpec::Version::STRING =~ /[a-zA-Z]+/
+      s.add_runtime_dependency "rspec-#{name}", "= #{RSpec::Version::STRING}"
+    else
+      s.add_runtime_dependency "rspec-#{name}", "~> #{RSpec::Version::STRING.split('.')[0..1].concat(['0']).join('.')}"
+    end
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-rspec.git



More information about the Pkg-ruby-extras-commits mailing list