language ReflectJava
kinds

	abstract Entity <: ENTITY

	PositionConstant <: ENTITY

	/* J A V A   D E C L A R A T I O N S */
	abstract NamedEntity <: Entity { identifier }
	abstract AccessibleEntity <: NamedEntity { accessibility, hostPackage }
	abstract TypedEntity <: NamedEntity { declaredType }
	abstract MemberOrConstructor <: AccessibleEntity { hostType }
	abstract MethodOrConstructor <: MemberOrConstructor
	
	Package <: NamedEntity

	abstract Type <: NamedEntity
	abstract DeclaredOrArrayType <: Type, AccessibleEntity
	
	DeclaredType <: DeclaredOrArrayType
	ArrayType <: DeclaredOrArrayType { nextLowerDimensionType }
	TypeVariable <: Type 
	
	Constructor <: MethodOrConstructor
	Field <: MemberOrConstructor, TypedEntity { }
	Method <: MethodOrConstructor, TypedEntity { }
	MethodParameter <: NamedEntity, TypedEntity { }
							  
	/*  R E F L E C T I O N  */
	abstract ReflectiveReference <: REFERENCE {hostType, hostPackage }

	abstract ReflectiveFieldNameReference <: ReflectiveReference { fieldName }
	abstract ReflectiveMethodNameReference <: ReflectiveReference { methodName }
	abstract ReflectiveTypeNameReference <: ReflectiveReference { typeName }
	abstract ReflectivePackageNameReference <: ReflectiveReference { packageName }

	abstract ReflectiveAccessModifierReference <: ReflectiveReference { returnedAccessModifier }
	abstract ReflectiveAccess <: ReflectiveReference { accessEnabled }

	abstract ReflectiveMemberReference <: ReflectiveReference
	abstract ReflectiveMemberSetReference <: ReflectiveReference
	abstract ReflectiveDeclaredMemberReference <: ReflectiveReference
	abstract ReflectiveDeclaredMemberSetReference <: ReflectiveReference
	abstract ReflectiveDeclaringClassReference <: ReflectiveReference

	// Class#forName(String className) 
	ClassForName <: ReflectiveTypeNameReference, ReflectivePackageNameReference {}

	// Class#getDeclaredField(String name)
	ClassGetDeclaredField <: ReflectiveFieldNameReference, ReflectiveDeclaredMemberReference {}

	// Class#getDeclaredFields()
	ClassGetDeclaredFields <: ReflectiveDeclaredMemberSetReference {}
	
	// Class#getDeclaredMethod(String, Class<?>...) 
	ClassGetDeclaredMethod <: ReflectiveMethodNameReference, ReflectiveDeclaredMemberReference {}
	
	// Class#getDeclaredMethods()
	ClassGetDeclaredMethods <: ReflectiveDeclaredMemberSetReference {}
	
	// Class#getDeclaredConstructor(String, Class<?>...) 
	ClassGetDeclaredConstructor <: ReflectiveMethodNameReference, ReflectiveDeclaredMemberReference {}
	
	// Class#getDeclaredConstructors()
	ClassGetDeclaredConstructors <: ReflectiveDeclaredMemberSetReference {}
	
	// Class#getField(String name)
	ClassGetField <: ReflectiveFieldNameReference, ReflectiveMemberReference {}

	// Class#getFields()
	ClassGetFields <: ReflectiveMemberSetReference {}

	// Class#getMethod(String, Class<?>...) 
	ClassGetMethod <: ReflectiveMethodNameReference, ReflectiveMemberReference {}

	// Class#getMethods()
	ClassGetMethods <: ReflectiveMemberSetReference { }
	
	// Class#getConstructor(String, Class<?>...) 
	ClassGetConstructor <: ReflectiveTypeNameReference, ReflectiveMemberReference {}

	// Class#getConstructors()
	ClassGetConstructors <: ReflectiveMemberSetReference { }
	
	// Field#get(Object obj)
	// Field#getBoolean(Object obj) 
	// Field#getByte(Object obj) 
	// Field#getChar(Object obj) 
	// Field#getDouble(Object obj) 
	// Field#getFloat(Object obj) 
	// Field#getInt(Object obj) 
	// Field#getLong(Object obj) 
	// Field#getShort(Object obj) 
	// Field#set(Object obj, Object value) 
	// Field#setBoolean(Object obj, boolean z) 
	// Field#setByte(Object obj, byte b) 
	// Field#setChar(Object obj, char c) 
	// Field#setDouble(Object obj, double d) 
	// Field#setFloat(Object obj, float f) 
	// Field#setInt(Object obj, int i) 
	// Field#setLong(Object obj, long l) 
	// Field#setShort(Object obj, short s) 
	FieldGetSet <: ReflectiveAccess { }                  

	// Field#getDeclaringClass()
	FieldGetDeclaringClass <: ReflectiveDeclaringClassReference { }
	
	// Field#getModifiers()
	FieldGetModifiers <: ReflectiveAccessModifierReference { }
	
	// Field#getName
	FieldGetName <: ReflectiveFieldNameReference { }

	// Field#toGenericString()
	FieldToGenericString <: ReflectiveFieldNameReference, 
	                        ReflectiveTypeNameReference, 
	                        ReflectivePackageNameReference, 
	                        ReflectiveAccessModifierReference,
	                        ReflectiveDeclaringClassReference { }
	
	// Method#getDeclaringClass() 
	MethodGetDeclaringClass <: ReflectiveReference {}
	
	// Method#getModifiers()
	MethodGetModifiers <: ReflectiveAccessModifierReference {}
	
	// Method#getName()
	MethodGetName <: ReflectiveMethodNameReference {}
	
	// Method#invoke(Object, Object...) 
	MethodInvoke <: ReflectiveAccess {}
	
	// Method#toGenericString
	MethodToGenericString <: ReflectiveMethodNameReference,
							 ReflectiveTypeNameReference,
							 ReflectivePackageNameReference,
							 ReflectiveAccessModifierReference,
							 ReflectiveDeclaringClassReference { }
	
	// Constructor#newInstance
	ConstructorNewInstance <: ReflectiveAccess
	
	// Constructor#toGenericString
	ConstructorToGenericString <: ReflectiveTypeNameReference,
							      ReflectivePackageNameReference,
							      ReflectiveAccessModifierReference,
							      ReflectiveDeclaringClassReference { }
	// Constructor#getName
	ConstructorGetName <: ReflectiveTypeNameReference
	
	// Constructor#getDeclaringClass
	ConstructorGetDeclaringClass <: ReflectiveDeclaringClassReference
	
	// Constructor#getModifiers()
	ConstructorGetModifiers <: ReflectiveAccessModifierReference {}
	
	
properties
	identifier: Identifier
	fieldName: Identifier
	methodName: Identifier
	typeName: Identifier
	packageName: Identifier
	accessibility: AccessModifier
	hostType: DeclaredType
	nextLowerDimensionType: DeclaredOrArrayType
	hostPackage : HostPackage
	declaredType: Type
	hostMethodOrConstructor: MethodOrConstructor
	position: Position
	/*  R E F L E C T I O N  */
	returnedAccessModifier : AccessModifier
	accessEnabled : AccessModifier // TODO: Change type to boolean
domains
	AccessModifier = {private, package, protected, public}
	HostPackage = [ Package ]
	Type = [ Type ]
	DeclaredOrArrayType = [ DeclaredOrArrayType ]
	DeclaredType = [ DeclaredType ]
	MethodOrConstructor = [ MethodOrConstructor ]
	Position = [PositionConstant]
queries
	/*  R E F L E C T I O N  */
	reflectiveBinding(r: ReflectiveReference, d: NamedEntity)
	reflectiveReceiver(r: ReflectiveAccess, e: DeclaredType)
	
	sub(t1 : Type, t2 : Type)
	member(T : Type, M : MemberOrConstructor)
	enclosed(Outer: AccessibleEntity, Inner: AccessibleEntity) // non transitive
	parameterPosition(P: MethodParameter, I: PositionConstant)
	hostMethod(M: MethodOrConstructor, P: MethodParameter)
	