<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_factory_details(self, name):
 # type: (str) -> Dict[str, Any] """ Retrieves a dictionary with details about the given factory * ``name``: The factory name * ``bundle``: The Bundle object of the bundle providing the factory * ``properties``: Copy of the components properties defined by the factory * ``requirements``: List of the requirements defined by the factory * ``id``: Requirement ID (field where it is injected) * ``specification``: Specification of the required service * ``aggregate``: If True, multiple services will be injected * ``optional``: If True, the requirement is optional * ``services``: List of the specifications of the services provided by components of this factory * ``handlers``: Dictionary of the non-built-in handlers required by this factory. The dictionary keys are handler IDs, and it contains a tuple with: * A copy of the configuration of the handler (0) * A flag indicating if the handler is present or not :param name: The name of a factory :return: A dictionary describing the factory :raise ValueError: Invalid factory """

        with self.__factories_lock:
            try:
                factory = self.__factories[name]
            except KeyError:
                raise ValueError("Unknown factory '{0}'".format(name))

            context = getattr(factory, constants.IPOPO_FACTORY_CONTEXT)
            assert isinstance(context, FactoryContext)

            result = {}  # type: Dict[Any, Any]
            # Factory name & bundle
            result["name"] = context.name
            result["bundle"] = context.bundle_context.get_bundle()

            # Configurable properties
            # Name -> Default value
            result["properties"] = {
                prop_name: context.properties.get(prop_name)
                for prop_name in context.properties_fields.values()
            }

            # Requirements (list of dictionaries)
            reqs = result["requirements"] = []
            handler_requires = context.get_handler(constants.HANDLER_REQUIRES)
            if handler_requires is not None:
                for field, requirement in handler_requires.items():
                    reqs.append(
                        {
                            "id": field,
                            "specification": requirement.specification,
                            "aggregate": requirement.aggregate,
                            "optional": requirement.optional,
                            "filter": requirement.original_filter,
                        }
                    )

            # Provided services (list of list of specifications)
            handler_provides = context.get_handler(constants.HANDLER_PROVIDES)
            if handler_provides is not None:
                result["services"] = [
                    specs_controller[0] for specs_controller in handler_provides
                ]
            else:
                result["services"] = []

            # Other handlers
            handlers = set(context.get_handlers_ids())
            handlers.difference_update(
                (
                    constants.HANDLER_PROPERTY,
                    constants.HANDLER_PROVIDES,
                    constants.HANDLER_REQUIRES,
                )
            )
            result["handlers"] = {
                handler: copy.deepcopy(context.get_handler(handler))
                for handler in handlers
            }

            return result