class NeighborsFilter implements ComplexFilter {

        private boolean self = true;
        private int depth = 1;

        @Override
        public Graph filter(Graph graph) {<FILL_FUNCTION_BODY>}

        @Override
        public String getName() {
            return NbBundle.getMessage(NeighborsBuilder.class, "NeighborsBuilder.name");
        }

        @Override
        public FilterProperty[] getProperties() {
            try {
                return new FilterProperty[] {
                    FilterProperty.createProperty(this, Integer.class, "depth"),
                    FilterProperty.createProperty(this, Boolean.class, "self")};
            } catch (NoSuchMethodException ex) {
                Exceptions.printStackTrace(ex);
            }
            return new FilterProperty[0];
        }

        public Integer getDepth() {
            return depth;
        }

        public void setDepth(Integer depth) {
            this.depth = depth;
        }

        public boolean isSelf() {
            return self;
        }

        public void setSelf(boolean self) {
            this.self = self;
        }
    }

            Set<Node> result = new HashSet<>();

            Collection<Node> nodes = graph.getNodes().toCollection();

            Set<Node> neighbours = new HashSet<>(nodes);

            //Put all neighbors into result
            Graph mainGraph = graph.getModel().getGraph();
            for (int i = 0; i < depth; i++) {
                boolean newNodes = false;
                Node[] nei = neighbours.toArray(new Node[0]);
                neighbours.clear();
                for (Node n : nei) {
                    //Extract all neighbors of n
                    for (Node neighbor : mainGraph.getNeighbors(n)) {
                        neighbours.add(neighbor);
                        newNodes = result.add(neighbor) || newNodes;
                    }
                }
                if (!newNodes || neighbours.isEmpty()) {
                    break;
                }
            }

            if (self) {
                result.addAll(nodes);
            } else {
                result.removeAll(nodes);
            }

            //Update nodes
            for (Node node : mainGraph.getNodes()) {
                if (result.contains(node)) {
                    graph.addNode(node);
                } else if (graph.contains(node)) {
                    graph.removeNode(node);
                }
            }

            //Update edges
            for (Edge edge : mainGraph.getEdges()) {
                if (graph.contains(edge.getSource()) && graph.contains(edge.getTarget())) {
                    graph.addEdge(edge);
                }
            }

            return graph;
        
<no_super_class>