def __parse_identities(self, json):
        """Parse identities using Sorting Hat format.

        The Sorting Hat identities format is a JSON stream on which its
        keys are the UUID of the unique identities. Each unique identity
        object has a list of identities and enrollments.

        When the unique identity does not have a UUID, it will be considered
        as an anonymous unique identity. This means that the UUID of these
        identities will be regenerated during the loading process.

        Next, there is an example of a valid stream:

        {
            "uidentities": {
                "johnsmith@example.net": {
                    "enrollments": [],
                    "identities": [],
                    "uuid": null
                },
                "03e12d00e37fd45593c49a5a5a1652deca4cf302": {
                    "enrollments": [
                        {
                            "end": "2100-01-01T00:00:00",
                            "start": "1900-01-01T00:00:00",
                            "organization": "Example",
                            "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                        }
                    ],
                    "identities": [
                        {
                            "email": "jsmith@example.com",
                            "id": "03e12d00e37fd45593c49a5a5a1652deca4cf302",
                            "name": "John Smith",
                            "source": "scm",
                            "username": "jsmith",
                            "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                        },
                        {
                            "email": "jsmith@example.com",
                            "id": "75d95d6c8492fd36d24a18bd45d62161e05fbc97",
                            "name": "John Smith",
                            "source": "scm",
                            "username": null,
                            "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                        }
                    ],
                    "profile": {
                        "country": {
                            "alpha3": "USA",
                            "code": "US",
                            "name": "United States of America"
                        },
                        "email": "jsmith@example.com",
                        "gender": "male",
                        "gender_acc": 100,
                        "name": null,
                        "is_bot": true,
                        "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                    },
                    "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                }
            }
        }

        :param stream: stream to parse

        :raises InvalidFormatError: raised when the format of the stream is
            not valid.
        """
        try:
            for uidentity in json['uidentities'].values():
                uuid = self.__encode(uidentity['uuid'])

                uid = UniqueIdentity(uuid=uuid)

                if uidentity['profile']:
                    profile = uidentity['profile']

                    if type(profile['is_bot']) != bool:
                        msg = "invalid json format. 'is_bot' must have a bool value"
                        raise InvalidFormatError(cause=msg)

                    is_bot = profile['is_bot']

                    gender = profile.get('gender', None)

                    if gender is not None:
                        gender = self.__encode(gender)

                    gender_acc = profile.get('gender_acc', None)

                    if gender_acc is not None:
                        if type(gender_acc) != int:
                            msg = "invalid json format. 'gender_acc' must have an integer value"
                            raise InvalidFormatError(cause=msg)
                        elif not 0 <= gender_acc <= 100:
                            msg = "invalid json format. 'gender_acc' is not in range (0,100)"
                            raise InvalidFormatError(cause=msg)

                    name = self.__encode(profile['name'])
                    email = self.__encode(profile['email'])

                    prf = Profile(uuid=uuid, name=name, email=email,
                                  gender=gender, gender_acc=gender_acc,
                                  is_bot=is_bot)

                    if profile['country']:
                        alpha3 = self.__encode(profile['country']['alpha3'])
                        code = self.__encode(profile['country']['code'])
                        name = self.__encode(profile['country']['name'])

                        c = Country(alpha3=alpha3, code=code, name=name)

                        prf.country_code = code
                        prf.country = c

                    uid.profile = prf

                for identity in uidentity['identities']:
                    identity_id = self.__encode(identity['id'])
                    name = self.__encode(identity['name'])
                    email = self.__encode(identity['email'])
                    username = self.__encode(identity['username'])
                    source = self.__encode(identity['source'])

                    sh_id = Identity(id=identity_id, name=name,
                                     email=email, username=username,
                                     source=source, uuid=uuid)

                    uid.identities.append(sh_id)

                for enrollment in uidentity['enrollments']:
                    organization = self.__encode(enrollment['organization'])

                    org = self._organizations.get(organization, None)

                    if not org:
                        org = Organization(name=organization)
                        self._organizations[organization] = org

                    try:
                        start = str_to_datetime(enrollment['start'])
                        end = str_to_datetime(enrollment['end'])
                    except InvalidDateError as e:
                        raise InvalidFormatError(cause=str(e))

                    rol = Enrollment(start=start, end=end, organization=org)

                    uid.enrollments.append(rol)

                self._identities.append(uid)
        except KeyError as e:
            msg = "invalid json format. Attribute %s not found" % e.args
            raise InvalidFormatError(cause=msg)
Parse identities using Sorting Hat format.

        The Sorting Hat identities format is a JSON stream on which its
        keys are the UUID of the unique identities. Each unique identity
        object has a list of identities and enrollments.

        When the unique identity does not have a UUID, it will be considered
        as an anonymous unique identity. This means that the UUID of these
        identities will be regenerated during the loading process.

        Next, there is an example of a valid stream:

        {
            "uidentities": {
                "johnsmith@example.net": {
                    "enrollments": [],
                    "identities": [],
                    "uuid": null
                },
                "03e12d00e37fd45593c49a5a5a1652deca4cf302": {
                    "enrollments": [
                        {
                            "end": "2100-01-01T00:00:00",
                            "start": "1900-01-01T00:00:00",
                            "organization": "Example",
                            "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                        }
                    ],
                    "identities": [
                        {
                            "email": "jsmith@example.com",
                            "id": "03e12d00e37fd45593c49a5a5a1652deca4cf302",
                            "name": "John Smith",
                            "source": "scm",
                            "username": "jsmith",
                            "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                        },
                        {
                            "email": "jsmith@example.com",
                            "id": "75d95d6c8492fd36d24a18bd45d62161e05fbc97",
                            "name": "John Smith",
                            "source": "scm",
                            "username": null,
                            "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                        }
                    ],
                    "profile": {
                        "country": {
                            "alpha3": "USA",
                            "code": "US",
                            "name": "United States of America"
                        },
                        "email": "jsmith@example.com",
                        "gender": "male",
                        "gender_acc": 100,
                        "name": null,
                        "is_bot": true,
                        "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                    },
                    "uuid": "03e12d00e37fd45593c49a5a5a1652deca4cf302"
                }
            }
        }

        :param stream: stream to parse

        :raises InvalidFormatError: raised when the format of the stream is
            not valid.