public static MutableString Join(ConversionStorage<MutableString>/*!*/ toPath, RubyClass/*!*/ self, params object[]/*!*/ parts) {
MutableString result = MutableString.CreateMutable(RubyEncoding.Binary);
Dictionary<object, bool> visitedLists = null;
var worklist = new Stack<object>();
int current = 0;
MutableString str;
Push(worklist, parts);
while (worklist.Count > 0) {
object part = worklist.Pop();
var list = part as IList;
if (list != null) {
if (list.Count == 0) {
str = MutableString.FrozenEmpty;
} else if (visitedLists != null && visitedLists.ContainsKey(list)) {
str = RubyUtils.InfiniteRecursionMarker;
} else {
if (visitedLists == null) {
visitedLists = new Dictionary<object, bool>(ReferenceEqualityComparer<object>.Instance);
}
visitedLists.Add(list, true);
Push(worklist, list);
continue;
}
} else if (part == null) {
throw RubyExceptions.CreateTypeConversionError("NilClass", "String");
} else {
str = Protocols.CastToPath(toPath, part);
}
if (current > 0) {
AppendDirectoryName(result, str);
} else {
result.Append(str);
}
current++;
}
return result;
}