code: static AbstractConfigValue resolveSubstitutions(ReplaceableMergeStack replaceable,
              List<AbstractConfigValue> stack, ResolveContext context) throws NotPossibleToResolve {
          // to resolve substitutions, we need to recursively resolve
          // the stack of stuff to merge, and merge the stack so
          // we won't be a delayed merge anymore. If restrictToChildOrNull
          // is non-null, we may remain a delayed merge though.
  
          int count = 0;
          AbstractConfigValue merged = null;
          for (AbstractConfigValue v : stack) {
              if (v instanceof ReplaceableMergeStack)
                  throw new ConfigException.BugOrBroken(
                          "A delayed merge should not contain another one: " + replaceable);
  
              boolean replaced = false;
              // we only replace if we have a substitution, or
              // value-concatenation containing one. The Unmergeable
              // here isn't a delayed merge stack since we can't contain
              // another stack (see assertion above).
              if (v instanceof Unmergeable) {
                  // If, while resolving 'v' we come back to the same
                  // merge stack, we only want to look _below_ 'v'
                  // in the stack. So we arrange to replace the
                  // ConfigDelayedMerge with a value that is only
                  // the remainder of the stack below this one.
  
                  context.source().replace((AbstractConfigValue) replaceable,
                          replaceable.makeReplacer(count + 1));
                  replaced = true;
              }
  
              AbstractConfigValue resolved;
              try {
                  resolved = context.resolve(v);
              } finally {
                  if (replaced)
                      context.source().unreplace((AbstractConfigValue) replaceable);
              }
  
              if (resolved != null) {
                  if (merged == null)
                      merged = resolved;
                  else
                      merged = merged.withFallback(resolved);
              }
              count += 1;
          }
  
          return merged;
      }
docs: static method also used by ConfigDelayedMergeObject