protected virtual object Visit(Sequence sequence)
        {
            Type targetType = this._targetType.Peek();
            object ret;

            if (targetType.IsArray)
            {
                Type elementType = targetType.GetElementType();
                Array newArray = Array.CreateInstance(elementType, sequence.Elements.Length);

                this._targetType.Push(elementType);
                for (int elemNum = 0; elemNum < sequence.Elements.Length; elemNum++)
                {
                    AstNode element = sequence.Elements[elemNum];

                    ValueError[] elementErrors = null;
                    using (ErrorCollector errors = new ErrorCollector(this))
                    {
                        object value = element.Visit(this);
                        if (errors.Count == 0)
                            newArray.SetValue(value, elemNum);

                        elementErrors = errors.ToArray();
                    }
                    this.RaiseError(elementErrors);
                }
                this._targetType.Pop();

                ret = newArray;
            }
            else
            {
                Type realType;
                if (targetType.IsInterface)
                    realType = OnResolveInterfaceType(targetType);
                else
                    realType = targetType;

                ret = Activator.CreateInstance(realType);

                MethodInfo[] addMethods =
                    realType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                            .Where(a => StringComparer.InvariantCultureIgnoreCase.Equals(a.Name, "Add"))
                            .ToArray();

                for (int elemNum = 0; elemNum < sequence.Elements.Length; elemNum++)
                {
                    List<ValueError> elementErrors = new List<ValueError>();
                    bool success = false;

                    for (int addNum = 0; addNum < addMethods.Length; addNum++)
                    {
                        ParameterInfo[] addParams = addMethods[addNum].GetParameters();

                        if (addParams.Length != 1)
                            continue;

                        this._targetType.Push(addParams[0].ParameterType);
                        using (ErrorCollector errors = new ErrorCollector(this))
                        {
                            object value = sequence.Elements[elemNum].Visit(this);

                            if (errors.Count == 0)
                            {
                                try
                                {
                                    addMethods[addNum].Invoke(ret, new[] {value});
                                    success = true;
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    this.RaiseError(new AddError(addMethods[addNum],
                                                                 new[] {value},
                                                                 new[] {sequence.Elements[elemNum]},
                                                                 ex));
                                }
                            }

                            elementErrors.AddRange(errors);
                        }
                        this._targetType.Pop();
                    }

                    if (!success)
                    {
                        this.RaiseError(elementErrors);
                    }
                }
            }

            return ret;
        }