+ /**
+ * Find statement context identified by interpreting specified {@link SchemaNodeIdentifier} starting at specified
+ * {@link StmtContext}.
+ *
+ * @param root Search root context
+ * @param identifier {@link SchemaNodeIdentifier} relative to search root
+ * @return Matching statement context, if present.
+ * @throws NullPointerException if any of the arguments is null
+ */
+ public static Optional<StmtContext<?, ?, ?>> findNode(final StmtContext<?, ?, ?> root,
+ final SchemaNodeIdentifier identifier) {
+ final Iterator<QName> iterator = identifier.getPathFromRoot().iterator();
+ if (!iterator.hasNext()) {
+ return Optional.of((Mutable<?, ?, EffectiveStatement<?, ?>>) root);
+ }
+
+ QName nextPath = iterator.next();
+ Mutable<?, ?, EffectiveStatement<?, ?>> current = root.getFromNamespace(ChildSchemaNodeNamespace.class,
+ nextPath);
+ if (current == null) {
+ return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(),
+ (Mutable<?, ?, EffectiveStatement<?, ?>>) root));
+ }
+ while (current != null && iterator.hasNext()) {
+ nextPath = iterator.next();
+ final Mutable<?, ?, EffectiveStatement<?, ?>> nextNodeCtx = current.getFromNamespace(
+ ChildSchemaNodeNamespace.class,nextPath);
+ if (nextNodeCtx == null) {
+ return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(), current));
+ }
+ current = nextNodeCtx;
+ }
+ return Optional.ofNullable(current);
+ }
+
+ @SuppressWarnings("unchecked")
+ static Mutable<?, ?, EffectiveStatement<?, ?>> tryToFindUnknownStatement(final String localName,
+ final Mutable<?, ?, EffectiveStatement<?, ?>> current) {
+ final Collection<? extends StmtContext<?, ?, ?>> unknownSubstatements = StmtContextUtils.findAllSubstatements(
+ current, UnknownStatement.class);
+ for (final StmtContext<?, ?, ?> unknownSubstatement : unknownSubstatements) {
+ if (localName.equals(unknownSubstatement.rawStatementArgument())) {
+ return (Mutable<?, ?, EffectiveStatement<?, ?>>) unknownSubstatement;
+ }
+ }
+ return null;
+ }
+