package com.github.simy4.xpath.expr.op;

import com.github.simy4.xpath.XmlBuilderException;
import com.github.simy4.xpath.navigator.Navigator;
import com.github.simy4.xpath.view.AbstractViewVisitor;
import com.github.simy4.xpath.view.LiteralView;
import com.github.simy4.xpath.view.NodeSetView;
import com.github.simy4.xpath.view.NodeView;
import com.github.simy4.xpath.view.NumberView;
import com.github.simy4.xpath.view.View;
import com.github.simy4.xpath.view.ViewVisitor;

public class Eq implements Op {

    @Override
    public <N> boolean test(View<N> left, View<N> right) {
        return 0 == left.compareTo(right);
    }

    @Override
    public <N> void apply(Navigator<N> navigator, View<N> left, View<N> right) throws XmlBuilderException {
        right.visit(new EqRightApplicationVisitor<N>(navigator, left));
    }

    @Override
    public String toString() {
        return "=";
    }

    private static final class EqRightApplicationVisitor<N> implements ViewVisitor<N, Void> {

        private final Navigator<N> navigator;
        private final View<N> left;

        private EqRightApplicationVisitor(Navigator<N> navigator, View<N> left) {
            this.navigator = navigator;
            this.left = left;
        }

        @Override
        public Void visit(NodeSetView<N> nodeSet) throws XmlBuilderException {
            if (nodeSet.toBoolean()) {
                return nodeSet.iterator().next().visit(this);
            }
            throw new XmlBuilderException("Can not modify empty node set");
        }

        @Override
        public Void visit(final LiteralView<N> literal) throws XmlBuilderException {
            return left.visit(new EqLeftApplicationVisitor<N>() {

                @Override
                public Void visit(NodeView<N> node) throws XmlBuilderException {
                    navigator.setText(node.getNode(), literal.getLiteral());
                    return null;
                }

            });
        }

        @Override
        public Void visit(final NumberView<N> number) throws XmlBuilderException {
            return left.visit(new EqLeftApplicationVisitor<N>() {

                @Override
                public Void visit(NodeView<N> node) throws XmlBuilderException {
                    navigator.setText(node.getNode(), number.getNumber().toString());
                    return null;
                }

            });
        }

        @Override
        public Void visit(final NodeView<N> rightNode) throws XmlBuilderException {
            return left.visit(new EqLeftApplicationVisitor<N>() {

                @Override
                public Void visit(NodeView<N> leftNode) throws XmlBuilderException {
                    navigator.setText(leftNode.getNode(), rightNode.getNode().getText());
                    return null;
                }

            });

        }

    }

    private abstract static class EqLeftApplicationVisitor<N> extends AbstractViewVisitor<N, Void> {

        @Override
        public final Void visit(NodeSetView<N> nodeSet) throws XmlBuilderException {
            if (!nodeSet.toBoolean()) {
                return returnDefault(nodeSet);
            }
            for (View<N> node : nodeSet) {
                node.visit(this);
            }
            return null;
        }

        @Override
        protected final Void returnDefault(View<N> view) throws XmlBuilderException {
            throw new XmlBuilderException("Can not modify read-only node: " + view);
        }

    }

}

@@ -196,56 +196,8 @@
 or;%0A
-import com.github.simy4.xpath.view.LiteralView;%0A
 impo
@@ -324,107 +324,12 @@
 iew.
-NumberView;%0Aimport com.github.simy4.xpath.view.View;%0Aimport com.github.simy4.xpath.view.ViewVisitor
+View
 ;%0A%0Ap
@@ -613,20 +613,19 @@
         
-righ
+lef
 t.visit(
@@ -630,20 +630,19 @@
 t(new Eq
-Righ
+Lef
 tApplica
@@ -667,19 +667,20 @@
 igator, 
-lef
+righ
 t));%0A   
@@ -788,20 +788,19 @@
 class Eq
-Righ
+Lef
 tApplica
@@ -814,27 +814,32 @@
 itor%3CN%3E 
-implement
+extend
 s 
+Abstract
 ViewVisi
@@ -930,19 +930,20 @@
 View%3CN%3E 
-lef
+righ
 t;%0A%0A    
@@ -960,12 +960,11 @@
 e Eq
-Righ
+Lef
 tApp
@@ -1011,19 +1011,20 @@
 View%3CN%3E 
-lef
+righ
 t) %7B%0A   
@@ -1081,18 +1081,20 @@
 his.
-left = lef
+right = righ
 t;%0A 
@@ -1128,32 +1128,38 @@
 %0A        public 
+final 
 Void visit(NodeS
@@ -1222,1058 +1222,110 @@
     
-if (nodeSet.toBoolean()) %7B%0A                return nodeSet.iterator().next().visit(this);%0A            %7D%0A            throw new XmlBuilderException(%22Can not modify empty node set%22);%0A        %7D%0A%0A        @Override%0A        public Void visit(final LiteralView%3CN%3E literal) throws XmlBuilderException %7B%0A            return left.visit(new EqLeftApplicationVisitor%3CN%3E() %7B%0A%0A                @Override%0A                public Void visit(NodeView%3CN%3E node) throws XmlBuilderException %7B%0A                    navigator.setText(node.getNode(), literal.getLiteral());%0A                    return null;%0A                %7D%0A%0A            %7D);%0A        %7D%0A%0A        @Override%0A        public Void visit(final NumberView%3CN%3E number) throws XmlBuilderException %7B%0A            return left.visit(new EqLeftApplicationVisitor%3CN%3E() %7B%0A%0A                @Override%0A                public Void visit(NodeView%3CN%3E node) throws XmlBuilderException %7B%0A                    navigator.setText(node.getNode(), number.getNumber().toString());%0A                    return null;%0A                %7D%0A%0A            %7D)
+for (View%3CN%3E node : nodeSet) %7B%0A                node.visit(this);%0A            %7D%0A            return null
 ;%0A  
@@ -1377,22 +1377,16 @@
 d visit(
-final 
 NodeView
@@ -1393,192 +1393,9 @@
 %3CN%3E 
-rightNode) throws XmlBuilderException %7B%0A            return left.visit(new EqLeftApplicationVisitor%3CN%3E() %7B%0A%0A                @Override%0A                public Void visit(NodeView%3CN%3E leftN
+n
 ode)
@@ -1436,24 +1436,16 @@
         
-        
 navigato
@@ -1458,13 +1458,9 @@
 ext(
-leftN
+n
 ode.
@@ -1479,518 +1479,21 @@
 ight
-Node.getNode().getText());%0A                    return null;%0A                %7D%0A%0A            %7D);%0A%0A        %7D%0A%0A    %7D%0A%0A    private abstract static class EqLeftApplicationVisitor%3CN%3E extends AbstractViewVisitor%3CN, Void%3E %7B%0A%0A        @Override%0A        public final Void visit(NodeSetView%3CN%3E nodeSet) throws XmlBuilderException %7B%0A            if (!nodeSet.toBoolean()) %7B%0A                return returnDefault(nodeSet);%0A            %7D%0A            for (View%3CN%3E node : nodeSet) %7B%0A                node.visit(this);%0A            %7D
+.toString());
 %0A   

Simplify Eq class