class urn_perun_resource_attribute_def_def_unixGID_namespace extends ResourceAttributesModuleAbstract implements ResourceAttributesModuleImplApi {

	@Override
	public void checkAttributeSemantics(PerunSessionImpl sess, Resource resource, Attribute attribute) throws WrongReferenceAttributeValueException, WrongAttributeAssignmentException{
		try{
			String gidNamespace = attribute.getFriendlyNameParameter();

			//Special behaviour if gid is null
			Integer attrValue;
			if(attribute.getValue() == null) {
				throw new WrongReferenceAttributeValueException(attribute, null, resource, null, "Unix GID must be set");
			} else {
				attrValue = attribute.valueAsInteger();
			}

			//Check if GID is within allowed range
			try {
				sess.getPerunBl().getModulesUtilsBl().checkIfGIDIsWithinRange(sess, attribute);
			} catch (WrongAttributeValueException ex) {
				throw new WrongReferenceAttributeValueException(ex);
			}

			//check if gid is not already depleted
			Attribute usedGids = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, gidNamespace, A_E_usedGids);
			//null in value means there is no depleted or used gids
			if(usedGids.getValue() != null) {
				Map<String, String> usedGidsValue = usedGids.valueAsMap();
				//Dx, where x is GID means depleted value for GID x
				if(usedGidsValue.containsKey("D" + attrValue.toString())) {
					throw new WrongReferenceAttributeValueException(attribute, usedGids, resource, null, gidNamespace, null, "This GID is already depleted.");
				}
			}

			//Prepare lists for all groups and resources with same GID in the same namespace

			//Prepare attributes for searching through groups and resources
			Attribute resourceGIDAttribute = attribute;
			Attribute groupGIDAttribute = new Attribute(sess.getPerunBl().getAttributesManagerBl().getAttributeDefinition(sess, A_G_unixGID_namespace + ":" + gidNamespace));
			groupGIDAttribute.setValue(resourceGIDAttribute.getValue());

			//Fill lists of Groups and Resources by data
			List<Group> allGroupsWithSameGIDInSameNamespace = new ArrayList<>(sess.getPerunBl().getGroupsManagerBl().getGroupsByAttribute(sess, groupGIDAttribute));
			List<Resource> allResourcesWithSameGIDInSameNamespace = new ArrayList<>(sess.getPerunBl().getResourcesManagerBl().getResourcesByAttribute(sess, resourceGIDAttribute));
			//remove this resource
			allResourcesWithSameGIDInSameNamespace.remove(resource);

			//Prepare list of GroupName attributes of this resource
			List <Attribute> groupNamesOfResource = sess.getPerunBl().getAttributesManagerBl().getAllAttributesStartWithNameWithoutNullValue(sess, resource, A_R_unixGroupName_namespace + ":");

			//Searching through groups
			if(!allGroupsWithSameGIDInSameNamespace.isEmpty()) {
				for(Group g: allGroupsWithSameGIDInSameNamespace) {
					for(Attribute a: groupNamesOfResource) {
						//Prepare group version of this group attribute
						Attribute groupGroupName = new Attribute(sess.getPerunBl().getAttributesManagerBl().getAttributeDefinition(sess, A_G_unixGroupName_namespace + ":" + a.getFriendlyNameParameter()));
						groupGroupName.setValue(a.getValue());

						int compare = sess.getPerunBl().getModulesUtilsBl().haveTheSameAttributeWithTheSameNamespace(sess, g, groupGroupName);

						if(compare > 0) {
							//This is problem, there is the same attribute but have other value
							throw new WrongReferenceAttributeValueException(attribute, a, "There is a group with same GID (namespace: "  + gidNamespace + ") and different unix group name (namespace: " + a.getFriendlyNameParameter() + "). " + g + " " + resource);
						}
						//Other possibilities are not problem, less than 0 mean that same attribute not exists, and 0 mean that attribute exists but have same value
					}
				}
			}

			//Searching through resources
			if(!allResourcesWithSameGIDInSameNamespace.isEmpty()) {
				for(Resource r: allResourcesWithSameGIDInSameNamespace) {
					for(Attribute a: groupNamesOfResource) {


						int compare = sess.getPerunBl().getModulesUtilsBl().haveTheSameAttributeWithTheSameNamespace(sess, r, a);

						if(compare > 0) {
							//This is problem, there is the same attribute but have other value
							throw new WrongReferenceAttributeValueException(attribute, a, "There is a resource with same GID (namespace: "  + gidNamespace + ") and different unix group name (namespace: " + a.getFriendlyNameParameter() + "). " + r + " " + resource);
						}
						//Other possibilities are not problem, less than 0 mean that same attribute not exists, and 0 mean that attribute exists but have same value
					}
				}
			}

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

}