def ajax_recalculate_records(self):
        """Recalculate all AR records and dependencies

            - samples
            - templates
            - profiles
            - services
            - dependecies

        XXX: This function has grown too much and needs refactoring!
        """
        out = {}

        # The sorted records from the request
        records = self.get_records()

        for n, record in enumerate(records):

            # Mapping of client UID -> client object info
            client_metadata = {}
            # Mapping of contact UID -> contact object info
            contact_metadata = {}
            # Mapping of sample UID -> sample object info
            sample_metadata = {}
            # Mapping of sampletype UID -> sampletype object info
            sampletype_metadata = {}
            # Mapping of specification UID -> specification object info
            specification_metadata = {}
            # Mapping of specification UID -> list of service UIDs
            specification_to_services = {}
            # Mapping of service UID -> list of specification UIDs
            service_to_specifications = {}
            # Mapping of template UID -> template object info
            template_metadata = {}
            # Mapping of template UID -> list of service UIDs
            template_to_services = {}
            # Mapping of service UID -> list of template UIDs
            service_to_templates = {}
            # Mapping of profile UID -> list of service UIDs
            profile_to_services = {}
            # Mapping of service UID -> list of profile UIDs
            service_to_profiles = {}
            # Profile metadata for UI purposes
            profile_metadata = {}
            # Mapping of service UID -> service object info
            service_metadata = {}
            # mapping of service UID -> unmet service dependency UIDs
            unmet_dependencies = {}

            # Mappings of UID -> object of selected items in this record
            _clients = self.get_objs_from_record(record, "Client_uid")
            _contacts = self.get_objs_from_record(record, "Contact_uid")
            _specifications = self.get_objs_from_record(
                record, "Specification_uid")
            _templates = self.get_objs_from_record(record, "Template_uid")
            _samples = self.get_objs_from_record(record, "PrimaryAnalysisRequest_uid")
            _profiles = self.get_objs_from_record(record, "Profiles_uid")
            _services = self.get_objs_from_record(record, "Analyses")
            _sampletypes = self.get_objs_from_record(record, "SampleType_uid")

            # CLIENTS
            for uid, obj in _clients.iteritems():
                # get the client metadata
                metadata = self.get_client_info(obj)
                # remember the sampletype metadata
                client_metadata[uid] = metadata

            # CONTACTS
            for uid, obj in _contacts.iteritems():
                # get the client metadata
                metadata = self.get_contact_info(obj)
                # remember the sampletype metadata
                contact_metadata[uid] = metadata

            # SPECIFICATIONS
            for uid, obj in _specifications.iteritems():
                # get the specification metadata
                metadata = self.get_specification_info(obj)
                # remember the metadata of this specification
                specification_metadata[uid] = metadata
                # get the spec'd service UIDs
                service_uids = metadata["service_uids"]
                # remember a mapping of specification uid -> spec'd services
                specification_to_services[uid] = service_uids
                # remember a mapping of service uid -> specifications
                for service_uid in service_uids:
                    if service_uid in service_to_specifications:
                        service_to_specifications[service_uid].append(uid)
                    else:
                        service_to_specifications[service_uid] = [uid]

            # AR TEMPLATES
            for uid, obj in _templates.iteritems():
                # get the template metadata
                metadata = self.get_template_info(obj)
                # remember the template metadata
                template_metadata[uid] = metadata

                # profile from the template
                profile = obj.getAnalysisProfile()
                # add the profile to the other profiles
                if profile is not None:
                    profile_uid = api.get_uid(profile)
                    _profiles[profile_uid] = profile

                # get the template analyses
                # [{'partition': 'part-1', 'service_uid': '...'},
                # {'partition': 'part-1', 'service_uid': '...'}]
                analyses = obj.getAnalyses() or []
                # get all UIDs of the template records
                service_uids = map(
                    lambda rec: rec.get("service_uid"), analyses)
                # remember a mapping of template uid -> service
                template_to_services[uid] = service_uids
                # remember a mapping of service uid -> templates
                for service_uid in service_uids:
                    # append service to services mapping
                    service = self.get_object_by_uid(service_uid)
                    # remember the template of all services
                    if service_uid in service_to_templates:
                        service_to_templates[service_uid].append(uid)
                    else:
                        service_to_templates[service_uid] = [uid]

                    # remember the service metadata
                    if service_uid not in service_metadata:
                        metadata = self.get_service_info(service)
                        service_metadata[service_uid] = metadata

            # PROFILES
            for uid, obj in _profiles.iteritems():
                # get the profile metadata
                metadata = self.get_profile_info(obj)
                # remember the profile metadata
                profile_metadata[uid] = metadata
                # get all services of this profile
                services = obj.getService()
                # get all UIDs of the profile services
                service_uids = map(api.get_uid, services)
                # remember all services of this profile
                profile_to_services[uid] = service_uids
                # remember a mapping of service uid -> profiles
                for service in services:
                    # get the UID of this service
                    service_uid = api.get_uid(service)
                    # add the service to the other services
                    _services[service_uid] = service
                    # remember the profiles of this service
                    if service_uid in service_to_profiles:
                        service_to_profiles[service_uid].append(uid)
                    else:
                        service_to_profiles[service_uid] = [uid]

            # PRIMARY ANALYSIS REQUESTS
            for uid, obj in _samples.iteritems():
                # get the sample metadata
                metadata = self.get_sample_info(obj)
                # remember the sample metadata
                sample_metadata[uid] = metadata

            # SAMPLETYPES
            for uid, obj in _sampletypes.iteritems():
                # get the sampletype metadata
                metadata = self.get_sampletype_info(obj)
                # remember the sampletype metadata
                sampletype_metadata[uid] = metadata

            # SERVICES
            for uid, obj in _services.iteritems():
                # get the service metadata
                metadata = self.get_service_info(obj)

                # remember the services' metadata
                service_metadata[uid] = metadata

            #  DEPENDENCIES
            for uid, obj in _services.iteritems():
                # get the dependencies of this service
                deps = get_service_dependencies_for(obj)

                # check for unmet dependencies
                for dep in deps["dependencies"]:
                    # we use the UID to test for equality
                    dep_uid = api.get_uid(dep)
                    if dep_uid not in _services.keys():
                        if uid in unmet_dependencies:
                            unmet_dependencies[uid].append(
                                self.get_base_info(dep))
                        else:
                            unmet_dependencies[uid] = [self.get_base_info(dep)]
                # remember the dependencies in the service metadata
                service_metadata[uid].update({
                    "dependencies": map(
                        self.get_base_info, deps["dependencies"]),
                })

            # Each key `n` (1,2,3...) contains the form data for one AR Add
            # column in the UI.
            # All relevant form data will be set accoriding to this data.
            out[n] = {
                "client_metadata": client_metadata,
                "contact_metadata": contact_metadata,
                "sample_metadata": sample_metadata,
                "sampletype_metadata": sampletype_metadata,
                "specification_metadata": specification_metadata,
                "specification_to_services": specification_to_services,
                "service_to_specifications": service_to_specifications,
                "template_metadata": template_metadata,
                "template_to_services": template_to_services,
                "service_to_templates": service_to_templates,
                "profile_metadata": profile_metadata,
                "profile_to_services": profile_to_services,
                "service_to_profiles": service_to_profiles,
                "service_metadata": service_metadata,
                "unmet_dependencies": unmet_dependencies,
            }

        return out
Recalculate all AR records and dependencies

            - samples
            - templates
            - profiles
            - services
            - dependecies

        XXX: This function has grown too much and needs refactoring!