/// <summary>
        /// Adds a new selector expression.
        /// </summary>
        /// <typeparam name="TProperty">The <see cref="Type"/> of the selected property.</typeparam>
        /// <param name="selector">The selector.</param>
        /// <exception cref="ArgumentNullException">The value of '<paramref name="selector"/>' cannot be null. </exception>
        public void SelectProperty <TProperty>([NotNull] Expression <Func <TRoot, TProperty> > selector)
        {
            this.ThrowIfPropertyDontParticipateInResponse(selector);

            var selectedTree = new FieldSelectorTreeCreator <TRoot>(this.partNameExtractor).GenerateFromLambdaExpression(selector);

            this.rootFieldSelectorParts.Add(selectedTree);
        }
        /// <summary>
        /// Builds the while selector expression that can be used be the request.
        /// It first, all <see cref="FieldSelectorTree"/> will be merged into one <see cref="FieldSelectorTree"/>.
        /// Next, the full tree for <typeparam name="TRoot"></typeparam> is generated.
        /// Than, the tree will be optimized, and last but not least: Build() is called on the optimized <see cref="FieldSelectorTree"/> and the value returned.
        /// </summary>
        /// <returns></returns>
        public String BuildSelectorExpression()
        {
            var mergedFieldSelectorPart = this.MergeRootParts(this.rootFieldSelectorParts);
            var maximumDeep             = mergedFieldSelectorPart.GetDeep();
            var fullFieldSelectorTree   = new FieldSelectorTreeCreator <TRoot>(this.partNameExtractor).GenerateFullFieldSelectorTree(maximumDeep);

            this.Optimize(mergedFieldSelectorPart, fullFieldSelectorTree);

            return(mergedFieldSelectorPart.Build());
        }
        /// <summary>
        /// Adds a new selector expression by first selecting a list and then by selecting properties of the items.
        /// </summary>
        /// <typeparam name="TItem">The <see cref="Type"/> of the list item.</typeparam>
        /// <typeparam name="TSubProperty">The <see cref="Type"/> of the sub property path.</typeparam>
        /// <param name="selector">The selector that selects the <see cref="IEnumerable{TItem}"/>.</param>
        /// <param name="subSelector">The selector that selects the property path of the item.</param>
        /// <exception cref="ArgumentNullException">The value of '<paramref name="selector"/>' and '<paramref name="subSelector"/>' cannot be null. </exception>
        public void SelectProperty <TItem, TSubProperty>([NotNull] Expression <Func <TRoot, IEnumerable <TItem> > > selector, [NotNull] Expression <Func <TItem, TSubProperty> > subSelector)
        {
            this.ThrowIfPropertyDontParticipateInResponse(selector);
            this.ThrowIfPropertyDontParticipateInResponse(subSelector);

            var collectionTree = new FieldSelectorTreeCreator <TRoot>(this.partNameExtractor).GenerateFromLambdaExpression(selector);
            var subTree        = new FieldSelectorTreeCreator <TItem>(this.partNameExtractor).GenerateFromLambdaExpression(subSelector);

            var lastChild = collectionTree.ChildParts.WhereRecursive(part => part.ChildParts, (part, deep) => !part.ChildParts.Any()).Single();

            lastChild.AddPart(subTree.ChildParts.First());

            this.rootFieldSelectorParts.Add(collectionTree);
        }