diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
index 56f1627..9c06053 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
@@ -15,6 +15,8 @@
  * Drupal's dependency injection container builder.
  *
  * @todo Submit upstream patches to Symfony to not require these overrides.
+ *
+ * @ingroup container
  */
 class ContainerBuilder extends SymfonyContainerBuilder {
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/ServiceModifierInterface.php b/core/lib/Drupal/Core/DependencyInjection/ServiceModifierInterface.php
index 000366c..08c881e 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ServiceModifierInterface.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ServiceModifierInterface.php
@@ -4,6 +4,8 @@
 
 /**
  * Interface that service providers can implement to modify services.
+ *
+ * @ingroup container
  */
 interface ServiceModifierInterface {
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/ServiceProviderBase.php b/core/lib/Drupal/Core/DependencyInjection/ServiceProviderBase.php
index c633395..49e9fbb 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ServiceProviderBase.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ServiceProviderBase.php
@@ -9,6 +9,8 @@
 
 /**
  * Base service provider implementation.
+ *
+ * @ingroup container
  */
 abstract class ServiceProviderBase implements ServiceProviderInterface, ServiceModifierInterface {
 
diff --git a/core/modules/system/core.api.php b/core/modules/system/core.api.php
index 19a4c37..8af5387 100644
--- a/core/modules/system/core.api.php
+++ b/core/modules/system/core.api.php
@@ -706,12 +706,121 @@
  * @{
  * Overview of the Dependency Injection Container and Services.
  *
- * @todo write this
- *
- * Additional documentation paragraphs need to be written, and functions,
- * classes, and interfaces need to be added to this topic.
+ * @section sec_overview Overview of container, injection, and services
+ * The Services and Dependency Injection Container concepts have been adopted by
+ * Drupal from the @link http://symfony.com/ Symfony framework. @endlink A
+ * "service" (such as accessing the database, sending email, or translating user
+ * interface text) is defined (given an name and an interface), and a default
+ * class is defined to provide the service. These two steps must be done
+ * together, and can be done by Drupal Core or a module. Other modules can then
+ * define alternative classes to provide the same services, overriding the
+ * default classes. Classes and functions that need to use the service should
+ * always instantiate the class via the dependency injection container (also
+ * known simply as the "container"), rather than instantiating a particular
+ * service provider class directly, so that they get the correct class
+ * (default or overridden).
+ *
+ * See https://drupal.org/node/2133171 for more detailed information on
+ * services and the dependency injection container.
+ *
+ * @section sec_discover Discovering existing services
+ * Drupal core defines many core services in the core.services.yml file (in the
+ * top-level core directory). Some Drupal Core modules and contributed modules
+ * also define services in modulename.services.yml files. API reference sites
+ * (such as https://api.drupal.org) generate lists of all existing services from
+ * these files, or you can look through the individual files manually.
+ *
+ * A typical service definition in a *.services.yml file looks like this:
+ * @code
+ * path.alias_manager:
+ *   class: Drupal\Core\Path\AliasManager
+ *   arguments: ['@path.crud', '@path.alias_whitelist', '@language_manager']
+ * @endcode
+ * The first line gives the unique machine name of the service (typically
+ * prefixed by the module name if provided by a module), and the class line
+ * gives the default class that provides the service. For some services, the
+ * arguments line lists the machine names of other services that are
+ * dependencies (preceded by '@'); objects for each of these services are
+ * instantiated from the container and passed to the class constructor when the
+ * service class is instantiated. Other arguments can also be passed in; see
+ * the section at https://drupal.org/node/2133171 for more detailed information.
+ *
+ * @section sec_container Accessing a service through the container
+ * As noted above, if you need to use a service in your code, you should always
+ * instantiate the service class via a call to the container, using the machine
+ * name of the service, so that the default class can be overridden. There are
+ * several ways to make sure this happens:
+ * - For service-providing classes, see other sections of this documentation
+ *   describing how to pass services as arguments to the constructor.
+ * - Plugin classes, controllers, and similar classes have create() methods,
+ *   whose first argument is
+ *   @code
+ *   \Symfony\Component\DependencyInjection\ContainerInterface $container
+ *   @endcode
+ *   In the create() method, call
+ *   @code $container->get('myservice.name') @endcode to instantiate a service.
+ *   The results of these calls are generally passed to the class constructor
+ *   and saved as member variables in the class.
+ * - For functions and class methods that do not have access to either of
+ *   the above methods of dependency injection, you can access the container
+ *   via a call to the global \Drupal class. This class has special methods for
+ *   accessing commonly-used services, or you can call a generic method to
+ *   access any service. Examples:
+ *   @code
+ *   // Retrieve the entity.manager service object (special method exists).
+ *   $manager = \Drupal->entityManager();
+ *   // Retrieve the service object for machine name 'foo.bar'.
+ *   $foobar = \Drupal->service('foo.bar');
+ *   @endcode
+ *
+ * @section sec_define Defining a service
+ * If your module needs to define a new service, here are the steps:
+ * - Choose a unique machine name for your service. Typically, this should
+ *   start with your module name. Example: mymodule.myservice.
+ * - Create a PHP interface to define what your service does.
+ * - Create a default class implementing your interface that provides your
+ *   service. If your class needs to use existing services (such as database
+ *   access), be sure to make these services arguments to your class
+ *   constructor, and save them in member variables. Also, if the needed
+ *   services are provided by other modules and not Drupal Core, you'll want
+ *   these modules to be dependencies of your module.
+ * - Add an entry to a modulename.services.yml file for the service. See
+ *   @ref sec_discover above, or existing services.yml files in Core, for the
+ *   syntax; it will start with your machine name, refer to your default class,
+ *   and list the services that need to be passed into your constructor.
+ *
+ * @section sec_injection Overriding the default service class
+ * Modules can override the default classes used for services. Here are the
+ * steps:
+ * - Define a class in the top-level namespace for your module
+ *   (Drupal\my_module), whose name is the camel-case version of your module's
+ *   machine name followed by "ServiceProvider" (for example, if your module
+ *   machine name is my_module, the class must be named
+ *   MyModuleServiceProvider).
+ * - The class needs to implement
+ *   \Drupal\Core\DependencyInjection\ServiceModifierInterface, which is
+ *   typically done by extending
+ *   \Drupal\Core\DependencyInjection\ServiceProviderBase.
+ * - Include a use statement for the class
+ *   \Drupal\Core\DependencyInjection\ContainerBuilder
+ * - The class needs to contain one method: alter(). This method does the
+ *   actual work of telling Drupal to use your class instead of the default.
+ *   Here's an example:
+ *   @code
+ *   public function alter(ContainerBuilder $container) {
+ *     // Override the language_manager class with a new class.
+ *     $definition = $container->getDefinition('language_manager');
+ *     $definition->setClass('Drupal\my_module\MyLanguageManager');
+ *   }
+ *   @endcode
+ *
+ * @see https://drupal.org/node/2133171
+ * @see core.services.yml
+ * @see \Drupal
+ * @see \Symfony\Component\DependencyInjection\ContainerInterface
+ * @see plugin_api
+ * @see menu
  *
- * See https://drupal.org/node/2133171
  * @}
  */
 
