Iterate through dynamic levels
You are using Conditional, and i would recommend replacing these with Visitor.

See Replace Conditional with Visitor article by Martin Fowler.

The generic visitor pattern in the code snippet belo is useful for all kind of added operation types on the hierrarchy:

using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace Traversal.Tests
{
    class VisitorTests
    {
        [Test]
        public void TestThis()
        {
            var topLevelResponse = new GroupResponse(
                new Response[]
                {
                    new ElementResponse("foo value", "foo"),
                    new GroupResponse(new[]
                        {
                            new ElementResponse("bar value", "bar")
                        })
                });

            var actualElement =
                topLevelResponse.Accept(new TraverseElementsVisitor()).FirstOrDefault(el =&gt; el.Reference == "bar");

            Assert.IsNotNull(actualElement);

            Assert.AreEqual("bar value", actualElement.Value);
        }
    }


    public interface IResponseVisitor&lt;T&gt;
    {
        T Visit(ElementResponse elementResponse);
        T Visit(GroupResponse groupResponse);
    }

    public abstract class Response
    {
        public abstract T Accept&lt;T&gt;(IResponseVisitor&lt;T&gt; visitor);
    }

    public class ElementResponse : Response
    {
        public ElementResponse(string value, string reference)
        {
            Reference = reference;
            Value = value;
        }

        public string Value { get; private set; }
        public string Reference { get; private set; }

        public override T Accept&lt;T&gt;(IResponseVisitor&lt;T&gt; visitor)
        {
            return visitor.Visit(this);
        }
    }

    public class GroupResponse : Response
    {
        public GroupResponse(IEnumerable&lt;Response&gt; responses)
        {
            Responses = responses;
        }

        public IEnumerable&lt;Response&gt; Responses { get; private set; }

        public override T Accept&lt;T&gt;(IResponseVisitor&lt;T&gt; visitor)
        {
            return visitor.Visit(this);
        }
    }

    public class TraverseElementsVisitor : IResponseVisitor&lt;IEnumerable&lt;ElementResponse&gt;&gt;
    {
        public IEnumerable&lt;ElementResponse&gt; Visit(ElementResponse elementResponse)
        {
            yield return elementResponse;
        }

        public IEnumerable&lt;ElementResponse&gt; Visit(GroupResponse groupResponse)
        {
            return groupResponse.Responses.SelectMany(r =&gt; r.Accept(this));
        }
    }
}


Your class hierarchy is not obvious to me, not sure i completely understand the class hierarchy you are using, so in the code example i provided a simplified one.

I'd say *Type postfix is redundant in this case, because you are using the objects to represent objects of a type, not the types themselves. Compare to usage of class name in System.Type, instances of which actually represent types.

Looks like you are putting same responsibility to multiple classes. Try to cleanly separate what is what, and what is common.