class urn_perun_group_attribute_def_def_unixGroupName_namespace extends GroupAttributesModuleAbstract implements GroupAttributesModuleImplApi {

	@Override
	public void checkAttributeSemantics(PerunSessionImpl sess, Group group, Attribute attribute) throws WrongReferenceAttributeValueException, WrongAttributeAssignmentException{
		//prepare namespace and groupName value variables
		String groupName = null;
		if(attribute.getValue() != null) groupName = attribute.valueAsString();
		String groupNameNamespace = attribute.getFriendlyNameParameter();

		if(groupName == null) {
			// if this is group attribute, its ok
			return;
		}

		try {
			//prepare attributes group and resource unixGroupName
			Attribute groupUnixGroupName = attribute;
			Attribute resourceUnixGroupName = new Attribute(sess.getPerunBl().getAttributesManagerBl().getAttributeDefinition(sess, A_R_unixGroupName_namespace + ":" + groupNameNamespace));
			resourceUnixGroupName.setValue(attribute.getValue());

			//prepare lists of groups and resources with the same groupName value in the same namespace

			//Fill lists of groups and resources
			List<Group> groupsWithSameGroupNameInTheSameNamespace = new ArrayList<>(sess.getPerunBl().getGroupsManagerBl().getGroupsByAttribute(sess, groupUnixGroupName));
			List<Resource> resourcesWithSameGroupNameInTheSameNamespace = new ArrayList<>(sess.getPerunBl().getResourcesManagerBl().getResourcesByAttribute(sess, resourceUnixGroupName));
			//Remove self from the list of groups with the same namespace
			//FIXME This behavior is not correct, because there are two possible situations:
			// - This is the Check right after setting a new value (correct behavior), we need to skip this value from checking
			// - This is the Check without setting a new value (not correct), and if this group is the only one with the value, we will lose the right for it
			groupsWithSameGroupNameInTheSameNamespace.remove(group);

			//If there is no group or resource with same GroupNameInTheSameNamespace, its ok
			if(groupsWithSameGroupNameInTheSameNamespace.isEmpty() && resourcesWithSameGroupNameInTheSameNamespace.isEmpty()) return;

			//First need to know that i have right to write any of duplicit groupName-namespace attribute
			boolean haveRights = sess.getPerunBl().getModulesUtilsBl().haveRightToWriteAttributeInAnyGroupOrResource(sess, groupsWithSameGroupNameInTheSameNamespace, resourcesWithSameGroupNameInTheSameNamespace, groupUnixGroupName, resourceUnixGroupName);
			if(!haveRights) throw new WrongReferenceAttributeValueException(attribute, null, group, null, "This groupName is already used for other group or resource and user has no rights to use it.");

			//Now if rights are ok, prepare lists of UnixGIDs attributes of this group (also equivalent resource GID)
			List<Attribute> groupUnixGIDs = sess.getPerunBl().getAttributesManagerBl().getAllAttributesStartWithNameWithoutNullValue(sess, group, A_G_unixGID_namespace + ":");
			List<Attribute> resourceVersionOfUnixGIDs = sess.getPerunBl().getModulesUtilsBl().getListOfResourceGIDsFromListOfGroupGIDs(sess, groupUnixGIDs);

			//In list of duplicit groups looking for GID in same namespace but with different value, thats not correct
			if(!groupsWithSameGroupNameInTheSameNamespace.isEmpty()) {
				for(Group g: groupsWithSameGroupNameInTheSameNamespace) {
					for(Attribute a: groupUnixGIDs) {
						int compare;
						compare = sess.getPerunBl().getModulesUtilsBl().haveTheSameAttributeWithTheSameNamespace(sess, g, a);

						if(compare > 0) {
							throw new WrongReferenceAttributeValueException(attribute, a, group, null, g, null, "One of the group GIDs is from the same namespace like other group GID but with different values.");
						}
					}
				}
			}

			//In list of duplicit resources looking for GID in same namespace but with different value, thats not correct
			if(!resourcesWithSameGroupNameInTheSameNamespace.isEmpty()) {
				for(Resource r: resourcesWithSameGroupNameInTheSameNamespace) {
					for(Attribute a: resourceVersionOfUnixGIDs) {
						int compare;
						compare = sess.getPerunBl().getModulesUtilsBl().haveTheSameAttributeWithTheSameNamespace(sess, r, a);

						if(compare > 0) {
							throw new WrongReferenceAttributeValueException(attribute, a, group, null, r, null, "One of the group GIDs is from the same namespace like other resource GIDs but with different values.");
						}
					}
				}
			}

		} catch(AttributeNotExistsException ex) {
			throw new ConsistencyErrorException(ex);
		}
	}

}