+ PathComponent component;
+ component.name = parse_name(path, i);
+ if (component.name[0] != '.')
+ component.index = parse_index(path, i);
+ else
+ component.index = -1;
+ return component;
+}
+
+
+/**
+ * Parse a path into its components.
+ */
+static void
+parse_path (const string &path, vector<PathComponent> &components)
+{
+ int pos = 0;
+ int max = path.size();
+
+ // Check for initial '/'
+ if (path[pos] == '/') {
+ PathComponent root;
+ root.name = "";
+ root.index = -1;
+ components.push_back(root);
+ pos++;
+ while (pos < max && path[pos] == '/')
+ pos++;
+ }
+
+ while (pos < max) {
+ components.push_back(parse_component(path, pos));
+ while (pos < max && path[pos] == '/')
+ pos++;
+ }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Other static utility functions.
+////////////////////////////////////////////////////////////////////////
+
+
+static const char *
+copy_string (const char * s)
+{
+ // FIXME: potential buffer overflow.
+ // For some reason, strnlen and
+ // strncpy cause all kinds of crashes.
+ string str = s;
+ char * copy = new char[str.size() + 1];
+ strcpy(copy, str.c_str());
+ return copy;
+}
+
+static bool
+compare_strings (const char * s1, const char * s2)
+{
+ return !strncmp(s1, s2, SGPropertyNode::MAX_STRING_LEN);
+}
+
+/**
+ * Locate a child node by name and index.
+ */
+static int
+find_child (const char * name, int index, vector<SGPropertyNode *> nodes)
+{
+ int nNodes = nodes.size();
+ for (int i = 0; i < nNodes; i++) {
+ SGPropertyNode * node = nodes[i];
+ if (compare_strings(node->getName(), name) && node->getIndex() == index)
+ return i;