class urn_perun_user_facility_attribute_def_virt_shell extends UserFacilityVirtualAttributesModuleAbstract implements UserFacilityVirtualAttributesModuleImplApi {

	@Override
	public Attribute getAttributeValue(PerunSessionImpl sess, User user, Facility facility, AttributeDefinition attributeDefinition) {
		Attribute attr = new Attribute(attributeDefinition);
		try {
			Attribute attribute = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, user, AttributesManager.NS_USER_FACILITY_ATTR_DEF + ":shell");
			if (attribute.getValue() != null) {
				Utils.copyAttributeToVirtualAttributeWithValue(attribute, attr);
				return attr;
			}
		} catch (WrongAttributeAssignmentException | AttributeNotExistsException ex) {
			throw new InternalErrorException(ex);
		}

		try {
			Attribute facilityShells = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, AttributesManager.NS_FACILITY_ATTR_DEF + ":shells");
			Attribute userPrefferedShells = (sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, user, AttributesManager.NS_USER_ATTR_DEF + ":preferredShells"));
			List<Resource> resources = sess.getPerunBl().getUsersManagerBl().getAllowedResources(sess, facility, user);
			Set<String> resourcesShells = new HashSet<>();

			for (Resource resource : resources) {
				List<String> resourcesShellsForTest = (List<String>) sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, resource, AttributesManager.NS_RESOURCE_ATTR_DEF + ":shells").getValue();
				if (resourcesShellsForTest != null) resourcesShells.addAll(resourcesShellsForTest);
			}
			if (userPrefferedShells.getValue() != null){
				for (String pShell : (List<String>)userPrefferedShells.getValue()) {
					if (resourcesShells.contains(pShell)) {
						Utils.copyAttributeToViAttributeWithoutValue(userPrefferedShells, attr);
						attr.setValue(pShell);
						return attr;
					}
				}
			}
			if (facilityShells.getValue() != null){
				for (String fShell : (List<String>)facilityShells.getValue()) {
					if (resourcesShells.contains(fShell)) {
						Utils.copyAttributeToViAttributeWithoutValue(facilityShells, attr);
						attr.setValue(fShell);
						return attr;
					}
				}
			}

		} catch (AttributeNotExistsException | WrongAttributeAssignmentException ex) {
			throw new InternalErrorException(ex);
		}
		return attr;

	}

}