diff --git a/src/main/java/spoon/reflect/visitor/filter/FieldReferenceFunction.java b/src/main/java/spoon/reflect/visitor/filter/FieldReferenceFunction.java
new file mode 100644
index 00000000000..91df5eab627
--- /dev/null
+++ b/src/main/java/spoon/reflect/visitor/filter/FieldReferenceFunction.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2017 INRIA and contributors
+ * Spoon - http://spoon.gforge.inria.fr/
+ *
+ * This software is governed by the CeCILL-C License under French law and
+ * abiding by the rules of distribution of free software. You can use, modify
+ * and/or redistribute the software under the terms of the CeCILL-C license as
+ * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package spoon.reflect.visitor.filter;
+
+import spoon.reflect.declaration.CtField;
+import spoon.reflect.reference.CtFieldReference;
+import spoon.reflect.visitor.chain.CtConsumableFunction;
+import spoon.reflect.visitor.chain.CtConsumer;
+
+/**
+ * This Query expects a {@link CtField} as input
+ * and returns all {@link CtFieldReference}s, which refers this input.
+ *
+ * Usage:
+ *
{@code
+ * CtField param = ...;
+ * param
+ * .map(new FieldReferenceFunction())
+ * .forEach((CtFieldReference ref)->...process references...);
+ * }
+ *
+ */
+public class FieldReferenceFunction implements CtConsumableFunction> {
+
+ public FieldReferenceFunction() {
+ }
+
+ @Override
+ public void apply(CtField> field, CtConsumer outputConsumer) {
+ field
+ .map(new FieldScopeFunction())
+ .filter(new DirectReferenceFilter>(field.getReference()))
+ .forEach(outputConsumer);
+ }
+}
diff --git a/src/main/java/spoon/reflect/visitor/filter/FieldScopeFunction.java b/src/main/java/spoon/reflect/visitor/filter/FieldScopeFunction.java
new file mode 100644
index 00000000000..46f7a41382b
--- /dev/null
+++ b/src/main/java/spoon/reflect/visitor/filter/FieldScopeFunction.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (C) 2006-2017 INRIA and contributors
+ * Spoon - http://spoon.gforge.inria.fr/
+ *
+ * This software is governed by the CeCILL-C License under French law and
+ * abiding by the rules of distribution of free software. You can use, modify
+ * and/or redistribute the software under the terms of the CeCILL-C license as
+ * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package spoon.reflect.visitor.filter;
+
+import spoon.reflect.declaration.CtField;
+import spoon.reflect.declaration.ModifierKind;
+import spoon.reflect.visitor.chain.CtConsumableFunction;
+import spoon.reflect.visitor.chain.CtConsumer;
+
+/**
+ * This Query expects a {@link CtField} as input
+ * and returns all CtElements,
+ * which are in visibility scope of that field.
+ * In other words, it returns all elements,
+ * which might be reference to that field.
+ *
+ * It can be used to search for variable declarations or
+ * variable references which might be in name conflict with input field.
+ *
+ * Usage:
+ * {@code
+ * CtField param = ...;
+ * param.map(new FieldScopeFunction()).forEach(...process result...);
+ * }
+ *
+ */
+public class FieldScopeFunction implements CtConsumableFunction> {
+
+ public FieldScopeFunction() {
+ }
+
+ @Override
+ public void apply(CtField> field, CtConsumer outputConsumer) {
+ if (field.hasModifier(ModifierKind.PRIVATE)) {
+ searchForPrivateField(field, outputConsumer);
+ } else if (field.hasModifier(ModifierKind.PUBLIC)) {
+ searchForPublicField(field, outputConsumer);
+ } else if (field.hasModifier(ModifierKind.PROTECTED)) {
+ searchForProtectedField(field, outputConsumer);
+ } else {
+ searchForPackageProtectedField(field, outputConsumer);
+ }
+ }
+ protected void searchForPrivateField(CtField> field, CtConsumer outputConsumer) {
+ //private field can be referred from the scope of current top level type only
+ field.getTopLevelType()
+ .filterChildren(null)
+ .forEach(outputConsumer);
+ }
+ protected void searchForProtectedField(CtField> field, CtConsumer outputConsumer) {
+ //protected field can be referred from the scope of current top level type only
+ field.getFactory().getModel().getRootPackage()
+ //search for all types which inherits from declaring type of this field
+ .filterChildren(new SubtypeFilter(field.getDeclaringType().getReference()))
+ //visit all elements in scope of these inherited types
+ .filterChildren(null)
+ .forEach(outputConsumer);
+ }
+ protected void searchForPublicField(CtField> field, CtConsumer outputConsumer) {
+ //public field is visible everywhere
+ field.getFactory().getModel().getRootPackage()
+ //visit all children of root package
+ .filterChildren(null)
+ .forEach(outputConsumer);
+ }
+ protected void searchForPackageProtectedField(CtField> field, CtConsumer outputConsumer) {
+ //package protected fields are visible in scope of the package of the top level type of the `field`
+ field.getTopLevelType().getPackage()
+ //visit all children of package, where top level type of the field is declared
+ .filterChildren(null)
+ .forEach(outputConsumer);
+ }
+}
diff --git a/src/main/java/spoon/reflect/visitor/filter/SubtypeFilter.java b/src/main/java/spoon/reflect/visitor/filter/SubtypeFilter.java
new file mode 100644
index 00000000000..ecf8091bb48
--- /dev/null
+++ b/src/main/java/spoon/reflect/visitor/filter/SubtypeFilter.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2006-2017 INRIA and contributors
+ * Spoon - http://spoon.gforge.inria.fr/
+ *
+ * This software is governed by the CeCILL-C License under French law and
+ * abiding by the rules of distribution of free software. You can use, modify
+ * and/or redistribute the software under the terms of the CeCILL-C license as
+ * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package spoon.reflect.visitor.filter;
+
+import spoon.reflect.declaration.CtType;
+import spoon.reflect.reference.CtTypeReference;
+import spoon.reflect.visitor.Filter;
+
+/**
+ * Matches all CtType elements, which are sub type of {@link #superType}
+ * Matches the input `superType` too.
+ * Call {@link #includingSelf(boolean)} with value false, if instance of {@link #superType} should no match this {@link Filter}
+ */
+public class SubtypeFilter extends AbstractFilter> {
+
+ private CtTypeReference> superType;
+ private String superTypeQualifiedName;
+
+ public SubtypeFilter(CtTypeReference> superType) {
+ this.superType = superType;
+ }
+
+ /**
+ * @param includingSelf if false then element which is equal to to #superType is not matching
+ */
+ public SubtypeFilter includingSelf(boolean includingSelf) {
+ if (includingSelf) {
+ superTypeQualifiedName = null;
+ } else {
+ superTypeQualifiedName = superType.getQualifiedName();
+ }
+ return this;
+ }
+
+ @Override
+ public boolean matches(CtType> mayBeSubType) {
+ if (superTypeQualifiedName != null && superTypeQualifiedName.equals(mayBeSubType.getQualifiedName())) {
+ //we should not accept superType
+ return false;
+ }
+ return mayBeSubType.isSubtypeOf(superType);
+ }
+}