Index: /applications/editors/josm/plugins/junctionchecking/README
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/README	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/README	(revision 25501)
@@ -0,0 +1,1 @@
+creates a channel digraph and checks a subset of channels if it is a junction or searches in a subset of channels for junctions
Index: /applications/editors/josm/plugins/junctionchecking/build.xml
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/build.xml	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/build.xml	(revision 25501)
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+** This is the build file for the junctionchecking plugin
+**
+** Maintaining versions
+** ====================
+** see README.template
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant  dist
+**
+** To install the generated plugin locally (in your default plugin directory) run
+**
+**    > ant  install
+**
+** To build against the core in ../../core, create a correct manifest and deploy to
+** SVN, 
+**    set the properties commit.message and plugin.main.version
+** and run
+**    > ant  publish
+**
+**
+-->
+<project name="junctionchecking" default="dist" basedir=".">
+
+	<property name="commit.message" value="Changed the constructor signature of the plugin main class" />
+	<property name="plugin.main.version" value="3751" />
+
+	<property name="josm" location="../../core/dist/josm-custom.jar" />
+	<property name="plugin.build.dir" value="build" />
+	<property name="plugin.src.dir" value="src" />
+	<!-- this is the directory where the plugin jar is copied to -->
+	<property name="plugin.dist.dir" value="../../dist" />
+	<property name="ant.build.javac.target" value="1.5" />
+	<property name="plugin.jar" value="${plugin.dist.dir}/${ant.project.name}.jar" />
+
+	<!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+	<target name="init">
+		<mkdir dir="${plugin.build.dir}" />
+	</target>
+
+	<!--
+    **********************************************************
+    ** compile - complies the source tree
+    **********************************************************
+    -->
+	<target name="compile" depends="init">
+		<echo message="compiling sources for  ${plugin.jar} ... " />
+		<javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}">
+			<compilerarg value="-Xlint:deprecation" />
+			<compilerarg value="-Xlint:unchecked" />
+		</javac>
+	</target>
+
+	<!--
+    **********************************************************
+    ** dist - creates the plugin jar
+    **********************************************************
+    -->
+	<!-- <target name="dist" depends="compile,revision">
+    -->
+	<target name="dist" depends="compile, revision">
+		<echo message="creating ${plugin.jar} ... " />
+		<copy todir="${plugin.build.dir}/resources">
+			<fileset dir="resources" />
+		</copy>
+		<copy todir="${plugin.build.dir}/images">
+			<fileset dir="images" />
+		</copy>
+		<copy todir="${plugin.build.dir}">
+			<fileset dir=".">
+				<include name="LICENSE" />
+				<include name="README" />
+			</fileset>
+		</copy>
+		<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
+			<manifest>
+				<attribute name="Author" value="Jörg Possin" />
+				<attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.JunctionChecker.JunctionCheckerPlugin" />
+				<attribute name="Plugin-Date" value="${version.entry.commit.date}" />
+				<attribute name="Plugin-Description" value="creates a channel digraph and checks a subset of channels if it is a junction or searches in a subset of channels for junctions" />
+				<attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/index.php/JOSM/Plugins/JunctionChecking" />
+				<attribute name="Plugin-Mainversion" value="${plugin.main.version}" />
+				<attribute name="Plugin-Version" value="${version.entry.commit.revision}" />
+				<attribute name="Plugin-Icon" value="images/dialogs/junctionchecker.png" />
+				<attribute name="Class-Path" value="resources/" />
+				<attribute name="Main-Class" value="org.openstreetmap.josm.plugins.JunctionChecker.commandlineinterface.CLI" />
+			</manifest>
+		</jar>
+	</target>
+
+	<!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+	 <target name="revision">
+
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+
+	<!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+	<target name="clean"> 
+        <delete dir="${plugin.build.dir}"/> 
+		<delete file="${plugin.jar}" />
+	</target>
+
+	<!--
+    **********************************************************
+    ** install - install the plugin in your local JOSM installation
+    **********************************************************
+    -->
+	<target name="install" depends="dist">
+		<property environment="env" />
+		<condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+			<and>
+				<os family="windows" />
+			</and>
+		</condition>
+		<copy file="${plugin.jar}" todir="${josm.plugins.dir}" />
+	</target>
+
+
+	<!--
+		 ************************** Publishing the plugin *********************************** 
+		-->
+	<!--
+		** extracts the JOSM release for the JOSM version in ../core and saves it in the 
+		** property ${coreversion.info.entry.revision}
+		**
+		-->
+	<target name="core-info">
+		<exec append="false" output="core.info.xml" executable="svn" failifexecutionfails="false">
+			<env key="LANG" value="C" />
+			<arg value="info" />
+			<arg value="--xml" />
+			<arg value="../../core" />
+		</exec>
+		<xmlproperty file="core.info.xml" prefix="coreversion" keepRoot="true" collapseAttributes="true" />
+		<echo>Building against core revision ${coreversion.info.entry.revision}.</echo>
+		<echo>Plugin-Mainversion is set to ${plugin.main.version}.</echo>
+		<delete file="core.info.xml" />
+	</target>
+
+	<!--
+		** commits the source tree for this plugin
+		-->
+	<target name="commit-current">
+		<echo>Commiting the plugin source with message '${commit.message}' ...</echo>
+		<exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+			<env key="LANG" value="C" />
+			<arg value="commit" />
+			<arg value="-m '${commit.message}'" />
+			<arg value="." />
+		</exec>
+	</target>
+
+	<!--
+		** updates (svn up) the source tree for this plugin
+		-->
+	<target name="update-current">
+		<echo>Updating plugin source ...</echo>
+		<exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+			<env key="LANG" value="C" />
+			<arg value="up" />
+			<arg value="." />
+		</exec>
+		<echo>Updating ${plugin.jar} ...</echo>
+		<exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+			<env key="LANG" value="C" />
+			<arg value="up" />
+			<arg value="../dist/${plugin.jar}" />
+		</exec>
+	</target>
+
+	<!--
+		** commits the plugin.jar 
+		-->
+	<target name="commit-dist">
+		<echo>
+	***** Properties of published ${plugin.jar} *****
+	Commit message    : '${commit.message}'					
+	Plugin-Mainversion: ${plugin.main.version}
+	JOSM build version: ${coreversion.info.entry.revision}
+	Plugin-Version    : ${version.entry.commit.revision}
+	***** / Properties of published ${plugin.jar} *****					
+						
+	Now commiting ${plugin.jar} ...
+	</echo>
+		<exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+			<env key="LANG" value="C" />
+			<arg value="-m '${commit.message}'" />
+			<arg value="commit" />
+			<arg value="${plugin.jar}" />
+		</exec>
+	</target>
+
+	<!-- ** make sure svn is present as a command line tool ** -->
+	<target name="ensure-svn-present">
+		<exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+			<env key="LANG" value="C" />
+			<arg value="--version" />
+		</exec>
+		<fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+			<!-- return code not set at all? Most likely svn isn't installed -->
+			<condition>
+				<not>
+					<isset property="svn.exit.code" />
+				</not>
+			</condition>
+		</fail>
+		<fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+			<!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+			<condition>
+				<isfailure code="${svn.exit.code}" />
+			</condition>
+		</fail>
+	</target>
+
+	<target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
+	</target>
+</project>
Index: /applications/editors/josm/plugins/junctionchecking/resources/xml/colorscheme.xml
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/resources/xml/colorscheme.xml	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/resources/xml/colorscheme.xml	(revision 25501)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ColorScheme>
+	<ToNode color="0,255,0" />
+	<FromNode color="0,255,0" />
+	<TwoWayChannel color="255,255,0" />
+	<OneWayChannel color="0,0,255" />
+	<NotConnectedChannel color="148,0,210" />
+	<selectedChannel color="255,0,0" />
+	<partOfJunction color="255,255,255" />
+</ColorScheme>	
Index: /applications/editors/josm/plugins/junctionchecking/resources/xml/waysfilter.xml
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/resources/xml/waysfilter.xml	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/resources/xml/waysfilter.xml	(revision 25501)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<highway entity="k">
+	<motorway entity="v" />
+	<motorway_link entity="v" />
+	<trunk entity="v" />
+	<trunk_link entity="v" />
+	<primary entity="v" />
+	<primary_link entity="v" />
+	<secondary entity="v" />
+	<tertiary entity="v" />
+	<residential entity="v" />
+	<living_street entity="v" />
+	<unclassified entity="v" />
+	<track entity="v" />
+</highway>
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/ChannelDiGraphLayer.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/ChannelDiGraphLayer.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/ChannelDiGraphLayer.java	(revision 25501)
@@ -0,0 +1,214 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMNode;
+import org.openstreetmap.josm.plugins.JunctionChecker.reader.ColorSchemeXMLReader;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * Diese Klasse enthält Teile der Klasse graphviewLayer des graphview Plugins
+ *
+ */
+public class ChannelDiGraphLayer extends Layer implements LayerChangeListener, PropertyChangeListener{
+
+	private ChannelDiGraph digraph;
+	private static final int POINTSIZE = 5;//original 3
+	private static final float LINEWIDTH = 4; //original 2
+	private final ColorSchemeXMLReader cXMLReader;
+	private static final Shape ARROW_HEAD;
+
+	static {
+		Polygon head = new Polygon();
+		head.addPoint(  0,  0);
+		head.addPoint(-15, +4);
+		head.addPoint(-15, -4);
+		ARROW_HEAD = head;
+	}
+
+	//die Farben für die zu zeichnenden Elemente
+	private Color twoWayChannelColor;
+	private Color oneWayChannelColor;
+	private Color toNodeColor;
+	private Color fromNodeColor;
+	private Color nsccChannelColor;
+	private Color selectedChannelColor;
+	private Color partOfJunctionColor;
+
+	public ChannelDiGraphLayer(ColorSchemeXMLReader cXMLReader){
+		super("ChannelDiGraphLayer");
+		MapView.addLayerChangeListener(this);
+		this.cXMLReader = cXMLReader;
+		initColors();
+	}
+
+	public void initColors() {
+		twoWayChannelColor = cXMLReader.getColor("TwoWayChannel");
+		oneWayChannelColor = cXMLReader.getColor("OneWayChannel");
+		toNodeColor = cXMLReader.getColor("ToNode");
+		fromNodeColor = cXMLReader.getColor("FromNode");
+		nsccChannelColor = cXMLReader.getColor("NotConnectedChannel");
+		selectedChannelColor = cXMLReader.getColor("selectedChannel");
+		partOfJunctionColor = cXMLReader.getColor("partOfJunction");
+	}
+
+	@Override
+	public Icon getIcon() {
+		return ImageProvider.get("dialogs", "junctionchecker");
+	}
+
+	@Override
+	public Object getInfoComponent() {
+		return null;
+	}
+
+	@Override
+	public Action[] getMenuEntries() {
+		Action[] action = new Action[0];
+		return action;
+	}
+
+	@Override
+	public String getToolTipText() {
+		return tr ("Channel-Digraph created from the active OSM-Layer");
+	}
+
+	@Override
+	public boolean isMergable(Layer other) {
+		return false;
+	}
+
+	@Override
+	public void mergeFrom(Layer from) {
+	}
+
+	@Override
+	public void paint(Graphics2D g, MapView mv, Bounds box) {
+		if (digraph != null) {
+			for (int i = 0; i < digraph.getChannels().size(); i++) {
+				paintChannel(digraph.getChannelAtPosition(i), g, mv);
+			}
+		}
+	}
+
+	private void paintChannel(final Channel channel, final Graphics2D g, final MapView mv) {
+		Point fromPoint = getCoord(channel.getFromNode(), mv);
+		g.setColor(fromNodeColor);
+		g.fillOval(fromPoint.x - POINTSIZE, fromPoint.y - POINTSIZE, 2 * POINTSIZE, 2 * POINTSIZE);
+		Point toPoint = getCoord(channel.getToNode(), mv);
+		g.setColor(toNodeColor);
+		g.fillOval(toPoint.x - POINTSIZE, toPoint.y - POINTSIZE, 2 * POINTSIZE, 2 * POINTSIZE);
+		Color c;
+		if (channel.isPartOfJunction()) {
+			c = partOfJunctionColor;
+		}
+		else if (channel.isSelected() == true) {
+			c = selectedChannelColor;
+		}
+		else if (channel.isStrongConnected() == false) {
+			c= nsccChannelColor;
+		}
+		else if (channel.getBackChannelID() != -100) {
+			c = twoWayChannelColor;
+		}
+		else {
+			c = oneWayChannelColor;
+		}
+		g.setColor(c);
+		g.setStroke(new BasicStroke(LINEWIDTH));
+		g.draw(new Line2D.Float(fromPoint.x, fromPoint.y, toPoint.x, toPoint.y));
+		double angle = angleFromXAxis(fromPoint, toPoint);
+		Shape head = ARROW_HEAD;
+		head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
+		head = AffineTransform.getTranslateInstance(toPoint.x, toPoint.y).createTransformedShape(head);
+		g.fill(head);
+
+	}
+
+	private Point getCoord(OSMNode node, MapView mv) {
+		return mv.getPoint(Main.proj.latlon2eastNorth(new LatLon(node.getLatitude(), node.getLongitude())));
+	}
+
+	/**
+	 * calculates the angle between the x axis and a vector given by two points
+	 * @param p1  first point for vector; != null
+	 * @param p2  second point for vector; != null
+	 * @return  angle in radians, in range [-Pi .. +Pi]
+	 */
+	private double angleFromXAxis(Point p1, Point p2) {
+		assert p1 != null && p2 != null;
+
+		final float vecX = p2.x - p1.x;
+		final float vecY = p2.y - p1.y;
+
+		final float vecLength = (float)Math.sqrt(vecX*vecX + vecY*vecY);
+
+		final float dotProductVecAxis = vecX;
+
+		float angle = (float)Math.acos(dotProductVecAxis / vecLength);
+
+		if (p2.y < p1.y) {
+			angle = -angle;
+		}
+
+		assert -Math.PI*0.5 < angle && angle <= Math.PI*0.5;
+
+		return angle;
+	}
+
+
+	@Override
+	public void visitBoundingBox(BoundingXYVisitor v) {
+	}
+
+	public void setDiGraph(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+	}
+
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+
+	}
+
+	public void layerAdded(Layer newLayer) {
+	}
+
+	public void layerRemoved(Layer oldLayer) {
+		if (oldLayer == this) {
+			MapView.removeLayerChangeListener(this);
+		}
+	}
+
+	public ChannelDiGraph getDigraph() {
+		return digraph;
+	}
+
+	public void setDigraph(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+	}
+
+	public void propertyChange(PropertyChangeEvent evt) {
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/DigraphCreationTask.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/DigraphCreationTask.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/DigraphCreationTask.java	(revision 25501)
@@ -0,0 +1,151 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSource;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.plugins.JunctionChecker.connectedness.DiGraphSealer;
+import org.openstreetmap.josm.plugins.JunctionChecker.connectedness.StrongConnectednessCalculator;
+import org.openstreetmap.josm.plugins.JunctionChecker.converting.ChannelDigraphBuilder;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.filter.ExecuteFilter;
+import org.openstreetmap.josm.plugins.JunctionChecker.reader.XMLFilterReader;
+import org.xml.sax.SAXException;
+
+/**
+ * Diese Klasse erstellt aus den Daten eines OSMDatenLayers den Channel-Digraphen
+ * Die dafür notwendigen Schritte werden von dieser Klasse angestoßen
+ * @author  joerg
+ */
+public class DigraphCreationTask extends PleaseWaitRunnable {
+
+	private final JunctionCheckerPlugin plugin;
+	private final boolean sealGraph;
+	private boolean canceled;
+	private final boolean calculateSCC;
+
+	private static final String WAYFILTERFILE = "/resources/xml/waysfilter.xml";
+
+	public DigraphCreationTask(JunctionCheckerPlugin plugin, boolean sealGraph, boolean calculateSCC) {
+		super(tr ("Create Channel Digraph"), false);
+		this.plugin = plugin;
+		this.sealGraph = sealGraph;
+		this.calculateSCC = calculateSCC;
+	}
+
+	@Override
+	protected void cancel() {
+		canceled = true;
+		progressMonitor.cancel();
+	}
+
+	@Override
+	protected void finish() {
+		if (canceled) {
+			Main.map.mapView.removeLayer(plugin.getChannelDigraphLayer());
+			return;
+		}
+	}
+
+	@Override
+	protected void realRun() throws SAXException, IOException,
+	OsmTransferException {
+		//Prüfen, ob der ausgewählte Layer ein OSMDataLayer ist
+		if (Main.map == null
+				|| !Main.map.isVisible() || !(Main.map.mapView.getActiveLayer() instanceof OsmDataLayer)) {
+			JOptionPane.showMessageDialog(Main.parent, tr("this layer is no osm data layer"));
+			return;
+		}
+		Main.main.removeLayer(plugin.getChannelDigraphLayer());
+		int tickscounter = 4;
+		if (sealGraph) {
+			tickscounter++;
+		}
+		if (calculateSCC) {
+			tickscounter++;
+		}
+		getProgressMonitor().setTicksCount(tickscounter);
+		tickscounter = 1;
+		getProgressMonitor().subTask(tr ("Converting OSM graph into Channel Digraph"));
+		getProgressMonitor().setTicks(tickscounter++);
+
+		OSMGraph graph = new OSMGraph();
+		//Der vom Benutzer in JOSM ausgewählte, zur Zeit aktive Layer wird der PLugin-OSM-Layer
+		plugin.setOsmlayer((OsmDataLayer)Main.map.mapView.getActiveLayer());
+		Iterator<Node> it = Main.main.getCurrentDataSet().getNodes().iterator();
+		while (it.hasNext()) {
+			graph.addNode(it.next());
+		}
+
+		Iterator<Way> itway = Main.main.getCurrentDataSet().getWays()
+		.iterator();
+		while (itway.hasNext()) {
+			graph.addWay(itway.next());
+		}
+		Iterator<Relation> itrel = Main.main.getCurrentDataSet().getRelations()
+		.iterator();
+		while (itrel.hasNext()) {
+			graph.addRelation(itrel.next());
+		}
+		Iterator<DataSource> itdata = Main.main.getCurrentDataSet().dataSources.iterator();
+		while (itdata.hasNext()) {
+			Bounds b = itdata.next().bounds;
+			graph.setBbbottom(b.getMin().getY());
+			graph.setBbleft(b.getMin().getX());
+			graph.setBbright(b.getMax().getX());
+			graph.setBbtop(b.getMax().getY());
+		}
+		getProgressMonitor().subTask(tr("filtering ways"));
+		getProgressMonitor().setTicks(tickscounter++);
+		// Filter mit gewünschten Ways laden
+		XMLFilterReader reader = new XMLFilterReader(
+				WAYFILTERFILE);
+		reader.parseXML();
+		// gewünschte Ways filtern
+		ExecuteFilter ef = new ExecuteFilter(reader.getFilters(), graph);
+		ef.filter();
+		getProgressMonitor().subTask(tr ("creating Channel-Digraph"));
+		getProgressMonitor().setTicks(tickscounter++);
+		// ChannelDiGraphen erzeugen
+		ChannelDigraphBuilder cdgb = new ChannelDigraphBuilder(ef.getOutgoinggraph());
+		cdgb.buildChannelDigraph();
+		StrongConnectednessCalculator scc = new StrongConnectednessCalculator(cdgb.getDigraph());
+		// DiGraph "versiegeln"
+		if (sealGraph) {
+			getProgressMonitor().subTask(tr ("sealing Digraph"));
+			getProgressMonitor().setTicks(tickscounter++);
+			DiGraphSealer sealer = new DiGraphSealer(cdgb.getDigraph(), cdgb
+					.getNewid());
+			sealer.sealingGraph();
+		}
+		//Digraph starke Zusammenhangskomponenten berechnen
+		if (calculateSCC) {
+			getProgressMonitor().subTask(tr ("calculating Strong Connectedness"));
+			getProgressMonitor().setTicks(tickscounter++);
+			scc.calculateSCC();
+		}
+		getProgressMonitor().subTask(tr ("creating DigraphLayer"));
+		getProgressMonitor().setTicks(tickscounter++);
+		plugin.setChannelDigraph(cdgb.getDigraph());
+		plugin.getOsmlayer().setBackgroundLayer(true);
+		plugin.getChannelDigraphLayer().setDigraph(cdgb.getDigraph());
+		plugin.setChannelDigraph(cdgb.getDigraph());
+		plugin.getJcMapMode().setDigraph(cdgb.getDigraph());
+		plugin.setNormalMapMode(Main.map.mapMode);
+		Main.map.selectMapMode(plugin.getJcMapMode());
+		Main.main.addLayer(plugin.getChannelDigraphLayer());
+		Main.map.mapView.setActiveLayer(plugin.getChannelDigraphLayer());
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckDialog.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckDialog.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckDialog.java	(revision 25501)
@@ -0,0 +1,151 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import static org.openstreetmap.josm.tools.I18n.marktr;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.border.TitledBorder;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * @author  joerg
+ */
+public class JunctionCheckDialog extends ToggleDialog implements ActionListener, SelectionChangedListener{
+
+	private final JunctionCheckerPlugin plugin;
+	/** Serializable ID */
+	private static final long serialVersionUID = 2952292777351992696L;
+	private final SideButton checkJunctionButton;
+	private final SideButton createDigraphButton;
+	private final SideButton searchJunctionButton;
+	private final JCheckBox digraphsealcb;
+	private final JCheckBox produceRelation;
+	private final JCheckBox sccCB;
+	private final JSpinner nways;
+	private final SpinnerNumberModel smodel;
+	private final JLabel nwayslabel;
+
+	public JunctionCheckDialog(JunctionCheckerPlugin junctionCheckerGuiPlugin) {
+		super(tr("JunctionChecking"), "junctionchecker", tr("Open the junctionchecking window."),
+				Shortcut.registerShortcut("subwindow:junctionchecker", tr("Toggle: {0}", tr("junctions")),
+						KeyEvent.VK_B, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
+		plugin = junctionCheckerGuiPlugin;
+		//das Digraph Create Panel
+		JPanel digraphPanel = new JPanel(new GridLayout(1, 2));
+		digraphPanel.setBorder(new TitledBorder(tr("Channel-Digraph creation")));
+		digraphsealcb = new JCheckBox(tr("seal Channel Digraph"));
+		digraphsealcb.setSelected(false);
+		//digraphPanel.add(digraphsealcb);
+
+		sccCB = new JCheckBox(tr("calculate strong connected channels"));
+		sccCB.setSelected(true);
+		digraphPanel.add(sccCB);
+
+		//das Panel zum Junctionchecken
+		JPanel jcPanel = new JPanel(new GridLayout(4, 1));
+		jcPanel.setBorder(new TitledBorder(tr("Junctionchecking/junctions searching")));
+
+		//Elemente für Grad-Auswahl der Kreuzung
+		JPanel spinnerpanel = new JPanel(new GridLayout(1,2));
+		smodel = new SpinnerNumberModel(3, 1, 20, 1);
+		nways = new JSpinner(smodel);
+		nwayslabel = new JLabel(tr("order of junction (n):"));
+		nwayslabel.setEnabled(false);
+		spinnerpanel.add(nwayslabel);
+		spinnerpanel.add(nways);
+
+		//Elemente zur OSM-Relationen-Erzeugung
+		produceRelation = new JCheckBox(tr("produce OSM-Relations: junction"));
+		produceRelation.setToolTipText(tr("if enabled the plugin produces osm-relations from the junction subgraphs"));
+		produceRelation.setSelected(true);
+		produceRelation.setEnabled(false);
+		jcPanel.add(produceRelation);
+		jcPanel.add(spinnerpanel);
+
+		JPanel centerPanel = new JPanel();
+		centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
+		centerPanel.add(digraphPanel);
+		centerPanel.add(jcPanel);
+
+		// ButtonPanel
+		JPanel buttonPanel = new JPanel();
+		buttonPanel.setLayout(new GridLayout(1, 3));
+		createDigraphButton = new SideButton(marktr("Create"), "digraphcreation", tr ("start the channel digraph creation"),
+				tr("create the channel digraph"), this);
+		buttonPanel.add(createDigraphButton);
+		checkJunctionButton = new SideButton(marktr("Check "), "junctioncheck", tr("check a marked subset if it is a junction"),
+				tr("check the subust for junction properties"), this);
+		checkJunctionButton.setEnabled(false);
+		buttonPanel.add(checkJunctionButton);
+		searchJunctionButton = new SideButton(marktr("Search "), "junctionsearch", tr ("search for junctions into a subset of channels"),
+				tr("search for junctions in the channel subset"), this);
+		searchJunctionButton.setEnabled(false);
+		buttonPanel.add(searchJunctionButton);
+
+		add(centerPanel, BorderLayout.CENTER);
+		add(buttonPanel, BorderLayout.SOUTH);
+	}
+
+
+	public void actionPerformed(ActionEvent e) {
+		String actionCommand = e.getActionCommand();
+		if (actionCommand.equals("Create")) {
+			DigraphCreationTask dct = new DigraphCreationTask(plugin, digraphsealcb.isSelected(), sccCB.isSelected());
+			Main.worker.submit(dct);
+			setActivateJunctionCheckOrSearch(true);
+		}
+		else if (actionCommand.equals("Check ")) {
+			PrepareJunctionCheckorSearch pjc = new PrepareJunctionCheckorSearch(plugin, smodel.getNumber().intValue(), produceRelation.isSelected());
+			pjc.prepareJunctionCheck();
+
+		}
+		else if (actionCommand.equals("Search ")) {
+			PrepareJunctionCheckorSearch pjc = new PrepareJunctionCheckorSearch(plugin, smodel.getNumber().intValue(), produceRelation.isSelected());
+			pjc.prepareJunctionSearch();
+		}
+	}
+
+	/**
+	 * (de)aktiviert Buttons zum JunctionCheck oder Suche
+	 * @param activate
+	 */
+	public void setActivateJunctionCheckOrSearch(boolean activate) {
+		checkJunctionButton.setEnabled(activate);
+		nways.setEnabled(activate);
+		nwayslabel.setEnabled(activate);
+		produceRelation.setEnabled(activate);
+		searchJunctionButton.setEnabled(activate);
+	}
+
+	/**
+	 * (de)aktiviert Buttons zur Channel Digraph Erstellung
+	 * @param activate
+	 */
+	public void setActivateCreateDigraph(boolean activate) {
+		createDigraphButton.setEnabled(activate);
+		digraphsealcb.setEnabled(activate);
+		sccCB.setEnabled(activate);
+	}
+
+	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckTask.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckTask.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckTask.java	(revision 25501)
@@ -0,0 +1,95 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking.JunctionChecker;
+import org.xml.sax.SAXException;
+
+/**
+ * Diese Klasse wird aufgerufen, wenn eine Teilmenge von Channels auf die Kreuzungskriterien geprüft
+ * wird.
+ * @author  joerg
+ */
+public class JunctionCheckTask extends PleaseWaitRunnable{
+
+	private final JunctionChecker jc;
+	private final JunctionCheckerPlugin plugin;
+	private final int n; //Grad der Kreuzung
+	private final HashSet<Channel> subset; //Teilmge der zu prüfenden Channel
+	private final boolean producerelation;
+	private boolean canceled;
+
+	public JunctionCheckTask(JunctionCheckerPlugin plugin, int n, HashSet<Channel> subset, boolean produceRelation) {
+		super("JunctionCheck", false);
+		this.plugin = plugin;
+		this.n = n;
+		this.subset = subset;
+		this.producerelation = produceRelation;
+		jc = new JunctionChecker(plugin.getChannelDigraph() , n);
+	}
+
+	@Override
+	protected void cancel() {
+		canceled = true;
+		progressMonitor.cancel();
+	}
+
+	@Override
+	protected void finish() {
+		if (canceled) {
+			return;
+		}
+		progressMonitor.finishTask();
+		if (jc.isSmallerJunction() ) {
+			showjunction();
+			JOptionPane.showMessageDialog(Main.parent, tr ("The marked channels contains a junctioncandidate (white). To test this candidat mark these channel and press the \"Check\" button again."));
+		}
+		else if (jc.getCheck()) {
+			showjunction();
+			JOptionPane.showMessageDialog(Main.parent, tr ("The marked channels are a {0}-ways junction", n));
+			plugin.getChannelDigraph().ereaseJunctioncandidate();
+			for (int i = 0; i < jc.getSubJunction().size(); i++) {
+				plugin.getChannelDigraph().addJunctioncandidateChannel(jc.getSubJunction().get(i));
+			}
+			if (producerelation) {
+				this.plugin.getRelationProducer().produceRelation(subset, n);
+			}
+		}
+		else if (!jc.getCheck()) {
+			JOptionPane.showMessageDialog(Main.parent, tr ("The marked channels are not a junction:") + jc.getJCheckResult());
+
+		}
+
+	}
+
+	@Override
+	protected void realRun() throws SAXException, IOException,
+	OsmTransferException {
+		jc.checkjunctions(new ArrayList<Channel>(subset), getProgressMonitor());
+	}
+
+	public JunctionChecker getJunctionChecker() {
+		return jc;
+	}
+
+	/**
+	 * zeigt den gefundenen Kreuzungskandidatena an
+	 */
+	private void showjunction() {
+		plugin.getChannelDigraph().ereaseJunctioncandidate();
+		for (int i = 0; i < jc.getSubJunction().size(); i++) {
+			plugin.getChannelDigraph().addJunctioncandidateChannel(jc.getSubJunction().get(i));
+		}
+		Main.map.mapView.setActiveLayer(plugin.getChannelDigraphLayer());
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckerMapMode.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckerMapMode.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckerMapMode.java	(revision 25501)
@@ -0,0 +1,164 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+
+/**
+ * Diese Klasse wurde aus der Klasse EditGpxMode Klasse des editGPX-Plugins erzeugt und nur an wenigen Stellen an
+ * die eigenen Bedürfnisse angepaßt
+ */
+public class JunctionCheckerMapMode extends MapMode implements LayerChangeListener{
+
+	MapFrame frame;
+	Point pointPressed;
+	ChannelDiGraphLayer layer;
+	Rectangle oldRect;
+	ChannelDiGraph digraph;
+
+	private static final long serialVersionUID = 3442408951505263850L;
+
+	public JunctionCheckerMapMode(MapFrame mapFrame, String name, String desc) {
+		super(name, "junctionchecker.png", desc, mapFrame, Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
+	}
+
+	@Override public void enterMode() {
+		super.enterMode();
+		Main.map.mapView.addMouseListener(this);
+		Main.map.mapView.addMouseMotionListener(this);
+		MapView.addLayerChangeListener(this);
+	}
+
+	@Override public void exitMode() {
+		super.exitMode();
+		Main.map.mapView.removeMouseListener(this);
+		Main.map.mapView.removeMouseMotionListener(this);
+	}
+
+
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+		if (newLayer instanceof ChannelDiGraphLayer) {
+			layer = (ChannelDiGraphLayer) newLayer;
+		}
+	}
+
+	public void layerAdded(Layer newLayer) {
+	}
+
+	public void layerRemoved(Layer oldLayer) {
+	}
+
+
+	public void setFrame(MapFrame newFrame) {
+		frame = newFrame;
+	}
+
+	@Override public void mousePressed(MouseEvent e) {
+		pointPressed = new Point(e.getPoint());
+	}
+
+
+	@Override public void mouseDragged(MouseEvent e) {
+		if ( (e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) ==  InputEvent.BUTTON1_DOWN_MASK) {
+			//if button1 is hold, draw the rectangle.
+			paintRect(pointPressed, e.getPoint());
+		}
+	}
+
+	@Override public void mouseReleased(MouseEvent e) {
+		if (e.getButton() != MouseEvent.BUTTON1) {
+			return;
+		}
+		digraph.ereaseJunctioncandidate();//um zu verhindern, dass gefundene Kreuzungen/Kandidaten weiterhin weiß gezeichnet werden
+		Point pointReleased = e.getPoint();
+
+		Rectangle r = createRect(pointReleased, pointPressed);
+		boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
+		boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
+		boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
+		if (shift == false) {
+			digraph.ereaseSelectedChannels();
+		}
+		//go through nodes and mark the ones in the selection rect as deleted
+		if (layer != null && digraph != null) {
+			LatLon lefttop = Main.map.mapView.getLatLon(r.x + r.width, r.y + r.height);
+			LatLon rightbottom = Main.map.mapView.getLatLon(r.x, r.y);
+			digraph.detectSelectedChannels(rightbottom.lon(), rightbottom.lat(), lefttop.lon(), lefttop.lat());
+		}
+		oldRect = null;
+		Main.map.mapView.repaint();
+
+	}
+
+	/**
+	 * create rectangle out of two given corners
+	 */
+	public Rectangle createRect(Point p1, Point p2) {
+		int x,y,w,h;
+		if (p1.x == p2.x && p1.y == p2.y) {
+			//if p1 and p2 same points draw a small rectangle around them
+			x = p1.x -1;
+			y = p1.y -1;
+			w = 3;
+			h = 3;
+		} else {
+			if (p1.x < p2.x){
+				x = p1.x;
+				w = p2.x-p1.x;
+			} else {
+				x = p2.x;
+				w = p1.x-p2.x;
+			}
+			if (p1.y < p2.y) {
+				y = p1.y;
+				h = p2.y-p1.y;
+			} else {
+				y = p2.y;
+				h = p1.y-p2.y;
+			}
+		}
+		return new Rectangle(x,y,w,h);
+	}
+
+	/**
+	 * Draw a selection rectangle on screen.
+	 */
+	private void paintRect(Point p1, Point p2) {
+		Graphics g = frame.getGraphics();//Main.map.mapView.getGraphics();
+
+		Rectangle r = oldRect;
+		if (r != null) {
+			//overwrite old rct
+			g.setXORMode(Color.BLACK);
+			g.setColor(Color.WHITE);
+			g.drawRect(r.x,r.y,r.width,r.height);
+		}
+
+		g.setXORMode(Color.BLACK);
+		g.setColor(Color.WHITE);
+		r = createRect(p1,p2);
+		g.drawRect(r.x,r.y,r.width,r.height);
+		oldRect = r;
+	}
+
+	public ChannelDiGraph getDigraph() {
+		return digraph;
+	}
+
+	public void setDigraph(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckerPlugin.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckerPlugin.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionCheckerPlugin.java	(revision 25501)
@@ -0,0 +1,131 @@
+/**
+ * License: GPL. Copyright 2011. Jörg Possin (joerg.possin@uni-muenster.de)
+ */
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.reader.ColorSchemeXMLReader;
+import org.openstreetmap.josm.plugins.JunctionChecker.util.RelationProducer;
+
+/**
+ * 
+ * This plugins helps to create a channel digraph und check channels in this network if it is a 
+ * junction or searches in a subgraph after junctions.
+ * 
+ */
+public class JunctionCheckerPlugin extends Plugin implements LayerChangeListener{
+
+	private static final String COLORSCHEMEFILTERFILE = "/resources/xml/colorscheme.xml";
+	private JunctionCheckDialog junctionCheckDialog;
+	private File pathDir;
+	private final RelationProducer relationproducer;
+	//Die benötigten Layer für JOSM
+	private OsmDataLayer osmlayer; //IN diesem Layer sind die Originaldaten gespiechert, aus denen der Channel-Digraph erzeugt wird
+	private ChannelDiGraphLayer channelDigraphLayer;
+	private final ColorSchemeXMLReader cXMLReaderMK;
+	private ChannelDiGraph channelDigraph;
+	private final JunctionCheckerMapMode jcMapMode;
+	private MapMode normalMapMode;
+
+	public JunctionCheckerPlugin(PluginInformation info) {
+		super(info);
+		jcMapMode = new JunctionCheckerMapMode(Main.map, "junctionchecking", tr("construct channel digraph and search for junctions"));
+		relationproducer = new RelationProducer(this);
+		cXMLReaderMK = new ColorSchemeXMLReader(COLORSCHEMEFILTERFILE);
+	}
+
+	@Override
+	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+		if (newFrame != null) {
+			junctionCheckDialog = new JunctionCheckDialog(this);
+			newFrame.addToggleDialog(junctionCheckDialog);
+			MapView.addLayerChangeListener(this);
+			jcMapMode.setFrame(newFrame);
+		} else
+			MapView.removeLayerChangeListener(this);
+	}
+
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+		if (newLayer instanceof OsmDataLayer) {
+			this.getJunctionCheckDialog().setActivateCreateDigraph(true);
+			this.getJunctionCheckDialog().setActivateJunctionCheckOrSearch(false);
+			if (normalMapMode != null) {
+				Main.map.selectMapMode(normalMapMode);
+			}
+		}
+		if (newLayer == channelDigraphLayer) {
+			this.getJunctionCheckDialog().setActivateCreateDigraph(false);
+			this.getJunctionCheckDialog().setActivateJunctionCheckOrSearch(true);
+			Main.map.selectMapMode(jcMapMode);
+		}
+	}
+
+	public void layerAdded(Layer newLayer) {
+	}
+
+	public void layerRemoved(Layer oldLayer) {
+		if (oldLayer == channelDigraphLayer) {
+			channelDigraphLayer = null;
+			this.getJunctionCheckDialog().setActivateJunctionCheckOrSearch(false);
+			return;
+		}
+		else {
+			this.getJunctionCheckDialog().setActivateCreateDigraph(false);
+		}
+	}
+
+	public ChannelDiGraphLayer getChannelDigraphLayer() {
+		if (channelDigraphLayer == null) {
+			channelDigraphLayer = new ChannelDiGraphLayer(cXMLReaderMK);
+		}
+		return channelDigraphLayer;
+	}
+
+	public JunctionCheckDialog getJunctionCheckDialog() {
+		return junctionCheckDialog;
+	}
+
+	public File getPathDir() {
+		return pathDir;
+	}
+
+	public OsmDataLayer getOsmlayer() {
+		return osmlayer;
+	}
+
+	public void setOsmlayer(OsmDataLayer osmlayer) {
+		this.osmlayer = osmlayer;
+	}
+
+	public RelationProducer getRelationProducer() {
+		return relationproducer;
+	}
+
+	public ChannelDiGraph getChannelDigraph() {
+		return channelDigraph;
+	}
+
+	public void setChannelDigraph(ChannelDiGraph channelDigraph) {
+		this.channelDigraph = channelDigraph;
+	}
+
+	public JunctionCheckerMapMode getJcMapMode() {
+		return jcMapMode;
+	}
+
+	public void setNormalMapMode(MapMode mm) {
+		normalMapMode = mm;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionSearchTask.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionSearchTask.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/JunctionSearchTask.java	(revision 25501)
@@ -0,0 +1,69 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking.JunctionChecker;
+import org.xml.sax.SAXException;
+
+/**
+ * Diese Klasse wird aufgerufen, wenn in einer Teilmenge von Channels nach Kreuzungen gesucht wird.
+ * @author  joerg
+ */
+public class JunctionSearchTask extends PleaseWaitRunnable{
+
+	private final JunctionChecker jc;
+	private final JunctionCheckerPlugin plugin;
+	private final int n;
+	private final HashSet<Channel> subset;
+	private final boolean produceRelation;
+	private boolean canceled;
+
+	public JunctionSearchTask(JunctionCheckerPlugin plugin, int n,
+			HashSet<Channel> subset,
+			boolean produceRelation) {
+		super("JunctionSearch",false);
+		this.plugin = plugin;
+		this.n = n;
+		this.subset = subset;
+		this.produceRelation = produceRelation;
+		jc = new JunctionChecker(plugin.getChannelDigraph(), n);
+	}
+
+	@Override
+	protected void cancel() {
+		this.canceled = true;
+		progressMonitor.cancel();
+	}
+
+	@Override
+	protected void finish() {
+		progressMonitor.finishTask();
+		if (canceled) {
+			return;
+		}
+		ArrayList<HashSet<Channel>> junctions = jc.getJunctions();
+		JOptionPane.showMessageDialog(Main.parent, tr ("Number of {0]-ways junctions found: ", n) + junctions.size() );
+		if (produceRelation) {
+			for (int i = 0; i < junctions.size(); i++) {
+				plugin.getRelationProducer().produceRelation(junctions.get(i) , n);
+			}
+		}
+	}
+
+	@Override
+	protected void realRun() throws SAXException, IOException,
+	OsmTransferException {
+		jc.junctionSearch(new ArrayList<Channel>(subset), getProgressMonitor());
+	}
+
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/PrepareJunctionCheckorSearch.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/PrepareJunctionCheckorSearch.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/PrepareJunctionCheckorSearch.java	(revision 25501)
@@ -0,0 +1,52 @@
+package org.openstreetmap.josm.plugins.JunctionChecker;
+
+import java.util.HashSet;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+
+/**
+ * prüft due Vorbedinungen des JunctionCheck oder Suche und übergibt die Parameter den Junction-Check-Klassen
+ * @author  joerg
+ */
+public class PrepareJunctionCheckorSearch {
+
+	private final JunctionCheckerPlugin plugin;
+	private final int n;
+	private HashSet<Channel> subset;
+	private JunctionCheckTask jct;
+	private final boolean produceRelation;
+
+	public PrepareJunctionCheckorSearch(JunctionCheckerPlugin plugin, int n, boolean producerelation) {
+		this.plugin = plugin;
+		this.n = n;
+		this.subset = new HashSet<Channel>();
+		this.produceRelation = producerelation;
+	}
+
+
+	protected void prepareJunctionCheck() {
+		if (prepareSubset()) {
+			jct = new JunctionCheckTask(plugin, n, subset, produceRelation);
+			Main.worker.submit(jct);
+		}
+	}
+
+	protected void prepareJunctionSearch() {
+		if (prepareSubset()) {
+			JunctionSearchTask jst = new JunctionSearchTask(plugin, n, subset, produceRelation);
+			Main.worker.submit(jst);
+		}
+	}
+
+	private boolean prepareSubset(){
+		if (plugin.getChannelDigraph().getSelectedChannels().size() < 6) {
+			JOptionPane.showMessageDialog(Main.parent, "Less then 6 channels are selected");
+			return false;
+		}
+		subset = plugin.getChannelDigraph().getSelectedChannels();
+		return true;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/commandlineinterface/CLI.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/commandlineinterface/CLI.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/commandlineinterface/CLI.java	(revision 25501)
@@ -0,0 +1,196 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.commandlineinterface;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.connectedness.StrongConnectednessCalculator;
+import org.openstreetmap.josm.plugins.JunctionChecker.converting.ChannelDigraphBuilder;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.filter.ExecuteFilter;
+import org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking.JunctionChecker;
+import org.openstreetmap.josm.plugins.JunctionChecker.reader.OSMXMLReader;
+import org.openstreetmap.josm.plugins.JunctionChecker.reader.XMLFilterReader;
+import org.openstreetmap.josm.plugins.JunctionChecker.writing.OSMXMLWriter;
+
+public class CLI {
+
+	/**
+	 * Die Klasse ist zum Erstellen statistischer Tests, oder zur Erzeugung einer Channel-Digraph-XML-Datei
+	 * @param args
+	 */
+	public static void main(String[] args) {
+
+		String inputosm = "";
+		String outputosm = "";
+		int maxchannelsearch = 0;
+		int ticks = 0;
+		int n = 0;
+		int runs = 0;
+
+		final String WAYFILTERFILE = "/resources/xml/waysfilter.xml";
+
+		if (args.length != 6) {
+			System.out.println("Parameter:\n inputosm (osmxml) \n outputchannelosm (outputosmxml) \n maxchannelsearch (wieviele channel sollen max. überprüft werdne) \n ticks (schrittweite) \n n (n-wege-kreuzung) \n durchläufe (wieviele durchläufe pro suchdurchgang)");
+			return;
+		} else {
+			inputosm = args[0];
+			outputosm = args[1];
+			maxchannelsearch = Integer.parseInt(args[2]);
+			ticks = Integer.parseInt(args[3]);
+			n = Integer.parseInt(args[4]);
+			runs = Integer.parseInt(args[5]);
+		}
+
+		// XML datei einlesen
+		File file = new File(inputosm);
+		OSMXMLReader xmlreader = new OSMXMLReader(file);
+		xmlreader.parseXML();
+
+		// Filter mit gewünschten Ways laden
+		XMLFilterReader reader = new XMLFilterReader(
+				WAYFILTERFILE);
+		reader.parseXML();
+
+		// gewünschte Ways filtern
+		ExecuteFilter ef = new ExecuteFilter(reader.getFilters(), xmlreader
+				.getOSMGraph());
+		ef.filter();
+
+		// ChannelDiGraphen erzeugen
+		ChannelDigraphBuilder cdgb = new ChannelDigraphBuilder(ef.getOutgoinggraph());
+		cdgb.buildChannelDigraph();
+
+		// DiGraph "versiegeln"
+		//DiGraphSealer sealer = new DiGraphSealer(cdgb.getDigraph(), cdgb
+		//		.getNewid());
+		//sealer.sealingGraph();
+
+		StrongConnectednessCalculator scc = new StrongConnectednessCalculator(cdgb.getDigraph());
+		scc.calculateSCC();
+		//System.out.println(scc.showNotstronglyConnectednessParts());
+
+		if (maxchannelsearch == 0) {
+			OSMXMLWriter oxw = new OSMXMLWriter(outputosm, cdgb.getDigraph());
+			try {
+				oxw.writeXML();
+			} catch (FileNotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (XMLStreamException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			;
+
+			System.out.println("OSMXML erzeugt, breche an dieser Stelle ab");
+			return;
+		}
+
+		JunctionChecker jc = new JunctionChecker(cdgb.getDigraph(), n);
+		ArrayList<Channel> subset = new ArrayList<Channel>();
+
+		Channel seed = new Channel();
+		Channel vorChannel;
+		Channel tempChannel;
+		boolean isIn = false;
+		int jcf;
+		long measuredIterateThroughTime = 0;
+		long measuredGenerateSubColumnTime = 0;
+		long measuredTime = 0;
+		long start;
+
+		//Unzusammenhängenden Teilgraph erzeugen
+		/*
+		for (int i = 6; i < maxchannelsearch; i = i + ticks) {
+			//diff = 0;
+			start = System.currentTimeMillis();
+			jcf = 0;
+			//System.out.println("maxchannel: " + i);
+			for (int j = 0; j < runs; j++) {
+				//System.out.println("run: " +j);
+				subset.clear();
+				for (int j2 = 0; j2 <= i; j2++) {
+					subset.add(cdgb.getDigraph()
+							.getChannelAtPosition(
+									(int) ((cdgb.getDigraph().getChannels()
+											.size()) * Math.random())));
+				}
+				//System.out.println("jc gestartet");
+				start = System.currentTimeMillis();
+				jc.junctionSearch(subset);
+				measuredTime += (System.currentTimeMillis() - start);
+				//System.out.println("jc beendet");
+				//diff = diff + (System.currentTimeMillis() - start);
+				measuredIterateThroughTime += jc.getMeasuredIterateTime();
+				measuredGenerateSubColumnTime += jc.getMeasuredGenerateTime();
+			}
+			System.out.println("Channels: " + (i) + " Time(Iterate): " + (measuredIterateThroughTime/runs) + " Time(Generate): " + (measuredGenerateSubColumnTime/runs) +" Time(overall): "+ (measuredTime/runs) + " junctionsfound: " + jcf);
+		}*/
+
+		//Zusammenhängenden Teilgraph erzeugen
+
+		for (int i = 5; i < maxchannelsearch; i = i + ticks) {
+			measuredIterateThroughTime = 0;
+			measuredGenerateSubColumnTime = 0;
+			measuredTime =0;
+			jcf = 0;
+			//System.out.println("maxchannel: " + i);
+			for (int j = 0; j < runs; j++) {
+				//System.out.println("run: " +j);
+				subset.clear();
+				do {
+					seed = cdgb.getDigraph()
+					.getChannelAtPosition(
+							(int) ((cdgb.getDigraph().getChannels()
+									.size()) * Math.random()));
+				}
+				while(!seed.isStrongConnected());
+				subset.add(seed);
+				//System.out.println("Seed: " + seed.getNewid());
+				vorChannel = seed;
+				for (int k = 0; k < i - 1; k++) {
+					isIn = false;
+					do {
+						tempChannel = getNeighbourChannel(vorChannel);
+						if (!subset.contains(tempChannel)) {
+							subset.add(tempChannel);
+							//System.out.println("zugefügt: " + tempChannel.getNewid());
+							seed = tempChannel;
+							isIn = true;
+						}
+						else {
+							vorChannel = tempChannel;
+							isIn = false;
+						}
+					}while (isIn == false);
+				}
+				start = System.currentTimeMillis();
+				jc.junctionSearch(subset);
+				measuredTime += (System.currentTimeMillis() - start);
+				//System.out.println("jc beendet");
+				measuredIterateThroughTime += jc.getMeasuredIterateTime();
+				measuredGenerateSubColumnTime += jc.getMeasuredGenerateTime();
+				jcf = jcf + jc.getJunctions().size();
+			}
+			System.out.println("Channels: " + (i) + " Time(Iterate): " + (measuredIterateThroughTime/runs) + " Time(Generate): " + (measuredGenerateSubColumnTime/runs) +" Time(overall): "+ (measuredTime/runs) + " junctionsfound: " + jcf);
+		}
+	}
+
+	private static Channel getNeighbourChannel(Channel seedChannel) {
+		if (Math.random() < 0.5) {
+			if (seedChannel.getPredChannels().size() >=1 ) {
+				return seedChannel.getPredChannels().get((int) (seedChannel.getPredChannels().size() * Math.random()));
+			}
+			else return seedChannel;
+		}
+		else {
+			if (seedChannel.getLeadsTo().size() >=1 ) {
+				return seedChannel.getLeadsTo().get((int) (seedChannel.getLeadsTo().size() * Math.random())).getToChannel();
+			}
+			else return seedChannel;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/BacktrackingColors.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/BacktrackingColors.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/BacktrackingColors.java	(revision 25501)
@@ -0,0 +1,12 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.connectedness;
+
+/**
+ * @author joerg
+ */
+public class BacktrackingColors {
+	
+	public static final int WHITE = -1;
+	public static final int GREY = 0;
+	public static final int BLACK = 1;
+
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/DiGraphSealer.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/DiGraphSealer.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/DiGraphSealer.java	(revision 25501)
@@ -0,0 +1,163 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.connectedness;
+
+import java.util.ArrayList;
+import java.util.Vector;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
+
+
+/**
+ * Diese Klasse versiegelt einen Digraphen, also die Enden eines outgoingChannels außerhalb einer Boundingbox werden mit dem Anfang eines bel. incomingChannels außerhalb der Boundigbox verbunden unbd umgekehrt
+ * @author  joerg
+ */
+public class DiGraphSealer {
+
+
+	// vorsichtshalber auf einen hohen negativen Wert gesetzt. besser
+	// automatisch setzen!
+	// TODO: NewID automatisch setzen
+	private int newID = 1000000;
+	private ChannelDiGraph digraph;
+
+	public DiGraphSealer(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+	}
+
+	public DiGraphSealer(ChannelDiGraph digraph, int newID) {
+		this.digraph = digraph;
+		this.newID = newID;
+	}
+
+	/**
+	 * versiegelt den vorher gesetzten DiGraphen
+	 */
+	public void sealingGraph() {
+		Vector<Integer> outgoingChannelIDs = new Vector<Integer>();
+		Vector<Integer> incomingChannelIDs = new Vector<Integer>();
+
+		for (int i = 0; i < digraph.numberOfChannels(); i++) {
+			if (digraph.isInBBox(digraph.getChannelAtPosition(i).getFromNode()) == false) {
+				incomingChannelIDs.add(i);
+			}
+			if (digraph.isInBBox(digraph.getChannelAtPosition(i).getToNode()) == false) {
+				outgoingChannelIDs.add(i);
+			}
+		}
+		int counter = 0;
+		Channel tempChannel;
+		LeadsTo tempLeadsTo;
+		for (int i = 0; i < outgoingChannelIDs.size(); i++) {
+			if (digraph.getChannelAtPosition(outgoingChannelIDs.get(i))
+					.getLeadsTo().size() == 0) {
+
+				tempChannel = new Channel(digraph.getChannelAtPosition(
+						outgoingChannelIDs.get(i)).getToNode(), digraph
+						.getChannelAtPosition(incomingChannelIDs.get(0))
+						.getFromNode());
+				//dem Channel auch den neuen Channel als Nachfolger übergeben!!!
+				//sonst gibts Probleme beim JunctionCheck
+				tempLeadsTo = new LeadsTo(digraph
+						.getChannelAtPosition(outgoingChannelIDs.get(i)),
+						tempChannel);
+				digraph.getChannelAtPosition(outgoingChannelIDs.get(i))
+						.addLeadsTo(tempLeadsTo);
+				digraph.addLeadsTo(tempLeadsTo);
+				tempLeadsTo = new LeadsTo(tempChannel, digraph
+						.getChannelAtPosition(incomingChannelIDs.get(0)));
+				tempChannel.addLeadsTo(tempLeadsTo);
+				digraph.addLeadsTo(tempLeadsTo);
+				tempChannel.addWay(digraph.getChannelAtPosition(
+						outgoingChannelIDs.get(i)).getWay());
+				tempChannel.setNewid(newID);
+				newID++;
+				digraph.addChannel(tempChannel);
+				counter++;
+			}
+		}
+
+		for (int i = 0; i < incomingChannelIDs.size(); i++) {
+			if (digraph.getChannelAtPosition(incomingChannelIDs.get(i))
+					.getPredChannels().size() == 0) {
+				tempChannel = new Channel(digraph.getChannelAtPosition(
+						outgoingChannelIDs.get(0)).getToNode(), digraph
+						.getChannelAtPosition(incomingChannelIDs.get(i))
+						.getFromNode());
+				//dem Channel auch den neuen Channel als Nachfolger überegeben
+				// sonst gibt es Probleme beim JuncitonCheck
+				digraph
+				.getChannelAtPosition(incomingChannelIDs.get(i)).addPredChannel(tempChannel);
+				tempLeadsTo = new LeadsTo(tempChannel, digraph
+						.getChannelAtPosition(incomingChannelIDs.get(i)));
+				tempChannel.addLeadsTo(tempLeadsTo);
+				digraph.addLeadsTo(tempLeadsTo);
+				tempLeadsTo = new LeadsTo(digraph
+						.getChannelAtPosition(outgoingChannelIDs.get(0)),
+						tempChannel);
+				digraph.getChannelAtPosition(outgoingChannelIDs.get(0))
+						.addLeadsTo(tempLeadsTo);
+				digraph.addLeadsTo(tempLeadsTo);
+				tempChannel.addWay(digraph.getChannelAtPosition(
+						incomingChannelIDs.get(i)).getWay());
+				tempChannel.setNewid(newID);
+				newID++;
+				digraph.addChannel(tempChannel);
+				counter++;
+			}
+		}
+		this.deleteDuplicateChannels();
+	}
+	
+	/*
+	private void showLeadsTo() {
+		for (int i = 0; i < digraph.getChannels().size(); i++) {
+			log.debug("Untersuche CHannel: " + digraph.getChannelAtPosition(i).getNewid());
+			for (int j = 0; j < digraph.getChannelAtPosition(i).getLeadsTo().size(); j++) {
+				log.debug("LeadsTo: " + digraph.getChannelAtPosition(i).getLeadsTo().get(j).toString());
+			}
+		}
+	}*/
+
+	/**
+	 * dirt'n'quick methode zum löschen doppelter channels TODO:
+	 * versiegeln-methode überarbeiten
+	 *TODO: benutze ich die überhaupt noch?
+	 */
+	private void deleteDuplicateChannels() {
+		ArrayList<Integer> pointer = new ArrayList<Integer>();
+
+		for (int i = 0; i < digraph.getChannels().size(); i++) {
+			for (int j = i + 1; j < digraph.getChannels().size(); j++) {
+				if (digraph.getChannelAtPosition(i).getFromNode() == digraph
+						.getChannelAtPosition(j).getFromNode()
+						&& digraph.getChannelAtPosition(i).getToNode() == digraph
+								.getChannelAtPosition(j).getToNode()) {
+					digraph.removeChannel(digraph.getChannelAtPosition(j));
+				}
+			}
+
+		}
+	}
+
+	/*
+	 * setzt Wert für IDs für neu angelegte Ways
+	 */
+	/**
+	 * @param newID
+	 */
+	public void setNewID(int newID) {
+		this.newID = newID;
+	}
+
+	/**
+	 * @return
+	 * @uml.property  name="newID"
+	 */
+	public int getNewID() {
+		return newID;
+	}
+
+	public ChannelDiGraph getDiGraph() {
+		return digraph;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/StrongConnectednessCalculator.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/StrongConnectednessCalculator.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/connectedness/StrongConnectednessCalculator.java	(revision 25501)
@@ -0,0 +1,135 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.connectedness;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+
+public class StrongConnectednessCalculator {
+
+	private int index = 0;
+	private final ArrayList<Channel> stack = new ArrayList<Channel>();
+	private final ArrayList<ArrayList<Channel>> SCC = new ArrayList<ArrayList<Channel>>();
+	private final int numberOfNodes;
+	private int calculatedNodes = 0;
+	private ArrayList<Channel> nsccchannels = new ArrayList<Channel>();
+	private final ChannelDiGraph digraph;
+	int biggestPart = 0;
+
+	public StrongConnectednessCalculator(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+		numberOfNodes = digraph.numberOfChannels();
+	}
+
+	private int findUncalculatedNodes() {
+		for (int i = 0; i < numberOfNodes; i++) {
+			if (digraph.getChannelAtPosition(i).getLowlink() == -1) {
+				return i;
+			}
+		}
+		return 0;
+	}
+
+	/**
+	 * berechnet die starken Zusammenhangskomponenten
+	 */
+	public void calculateSCC() {
+		while (calculatedNodes != numberOfNodes) {
+			//log.trace("calculatedNodes: " + calculatedNodes + ", gesamtnodes: " + numberOfNodes);
+			tarjan(digraph.getChannelAtPosition(findUncalculatedNodes()));
+		}
+		//log.trace("Berechnung der starken Zusammenhangskomponenten beendet: \n " +numberOfNodes + " Nodes sind wie folgt aufgeteilt: ");
+		for (int i = 0; i < SCC.size(); i++) {
+			//log.trace("Komponente: " + i + " besteht aus " + SCC.get(i).size()+ " Knoten");
+			/**
+			 * for (int j = 1; j < list.getNumberOfNodes(); j++) { if
+			 * (list.getAdjacencyListnodes()[j].getIndex()== -1) {
+			 * System.out.println("====");
+			 * System.out.println(list.getAdjacencyListnodes
+			 * ()[j].getNode().toString()); } }
+			 **/
+		}
+		findBiggestPiece();
+		saveNotSCCChannel();
+	}
+
+	/**
+	 * speichert alle Channel, die nicht stark zusammenhängend sind, in einer ArrayList
+	 **/
+	private void saveNotSCCChannel() {
+		nsccchannels = new ArrayList<Channel>();
+		for (int i = 0; i < SCC.size(); i++) {
+			if (i != biggestPart) {
+				nsccchannels.addAll(SCC.get(i));
+			}
+		}
+		//alle Channels auf nicht zusammenhängend setzen
+		for (int i = 0; i < nsccchannels.size(); i++) {
+			nsccchannels.get(i).setStrongConnected(false);
+		}
+	}
+
+	private void findBiggestPiece() {
+		int number = 0;
+		for (int i = 0; i < SCC.size(); i++) {
+			if (SCC.get(i).size() > number) {
+				biggestPart = i;
+				number = SCC.get(i).size();
+			}
+		}
+	}
+
+	public String showNotstronglyConnectednessParts() {
+		String s = new String();
+		for (int i = 0; i < SCC.size(); i++) {
+			if (i != biggestPart) {
+				s += "GraphKomponente: " + i + "\n";
+				for (int j = 0; j < SCC.get(i).size(); j++) {
+					s += "Channel: " + SCC.get(i).get(j).getNewid();
+				}
+				s += "\n";
+			}
+		}
+		return s;
+	}
+
+	/**
+	 * gibt eine Arraylist mit all den Channels zurück, welche nicht
+	 * im größten zusammenhägendem Teil des Channel-Digraphen sind
+	 * @return
+	 */
+	public ArrayList<Channel> getNotConnectedChannels() {
+		return nsccchannels;
+	}
+
+	private void tarjan(Channel v) {
+		//log.trace("tarjan für channel aufgerufen mit id: " + v.getNewid());
+		v.setIndex(index);
+		v.setLowlink(index);
+		index++;
+		stack.add(0, v);
+		//log.trace("channel "+v.getNewid() + " hat nachbarn: " + v.getLeadsTo().size());
+		for (int i = 0; i < v.getLeadsTo().size(); i++) {
+			//log.trace("schleifendurchlauf: " + i);
+			Channel n = v.getLeadsTo().get(i).getToChannel();
+			if (n.getIndex() == -1) {
+				//log.trace("n hat index =-1");
+				tarjan(n);
+				v.setLowlink(Math.min(v.getLowlink(), n.getLowlink()));
+			}
+			else if (stack.contains(n)) {
+				//log.trace("setze lowlink von n auf: " + v.getLowlink());
+				v.setLowlink(Math.min(v.getLowlink(), n.getLowlink()));
+			}
+		}
+		if (v.getLowlink() == v.getIndex()) {
+			Channel n;
+			ArrayList<Channel> component = new ArrayList<Channel>();
+			do {
+				n = stack.remove(0);
+				component.add(n);
+			} while (n != v);
+			SCC.add(component);
+			calculatedNodes += component.size();
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/ChannelDigraphBuilder.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/ChannelDigraphBuilder.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/ChannelDigraphBuilder.java	(revision 25501)
@@ -0,0 +1,153 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.converting;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMNode;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMWay;
+
+/**
+ * erstellt einen ChannelDigraphen aus einem OSMGraphen
+ * @author  Jörg Possin
+ */
+public class ChannelDigraphBuilder {
+
+	private final ChannelDiGraph digraph;
+	private final OSMGraph osmgraph;
+	private final OSMWay[] osmways;
+	private Channel newChannel = new Channel();
+	private final NodesConnectionProducer ncp;
+	// Variable wird für die IDs der neu erstellten Ways benötigt, die
+	// Hinrichtung bekommt den des ursprungs-Way, die Rückrichtung
+	// eine fiktive negative (OSM-XML-Standard für neue, noch nicht in der DB
+	// gespeicherte Entities)
+	private int newid = 1;
+	private TurnRestrictionChecker trchecker;
+	Channel backChannel;
+
+	public ChannelDigraphBuilder(OSMGraph osmgraph) {
+		//Nodesbeziehungen erstellen
+		ncp = new NodesConnectionProducer(osmgraph);
+		ncp.produceNodesConnections();
+		digraph = new ChannelDiGraph();
+		this.osmways = osmgraph.getWays();
+		digraph.setBbbottom(osmgraph.getBbbottom());
+		digraph.setBbleft(osmgraph.getBbleft());
+		digraph.setBbright(osmgraph.getBbright());
+		digraph.setBbtop(osmgraph.getBbtop());
+		this.osmgraph = osmgraph;
+	}
+
+	private void setNewWayID(Channel channel) {
+		channel.setNewid(newid);
+		newid++;
+	}
+
+	/**
+	 * Hilfemethode zur Erstellung eines Channels
+	 * @param fromNode fromNode des zu erstellenden Channels
+	 * @param toNode toNode  des zu erstellnenden Channels
+	 * @param way ein zu dem Channel gehörender Way
+	 * @return
+	 */
+	private Channel createChannel(OSMNode fromNode, OSMNode toNode, OSMWay way) {
+		newChannel = new Channel();
+		newChannel.setFromNode(fromNode);
+		newChannel.setToNode(toNode);
+		setNewWayID(newChannel);
+		digraph.addChannel(newChannel);
+		fromNode.addOutgoingChannel(newChannel);
+		newChannel.addWay(way);
+		return newChannel;
+	}
+
+	private void createBackChannel(OSMNode fromNode, OSMNode toNode, OSMWay way, Channel channel) {
+		backChannel = new Channel();
+		backChannel = createChannel(fromNode, toNode, way);
+		backChannel.setBackChannelID(channel.getNewid());
+		channel.setBackChannelID(backChannel.getNewid());
+	}
+
+	/**
+	 * erzeugt den Digraphen
+	 */
+	private void buildChannels(OSMWay way, boolean oneway) {
+		Channel tempChannel = new Channel();
+
+		OSMNode lastUsedNode = way.getFromNode();
+		OSMNode[] nodes = way.getNodes();
+		/*
+		 * log.debug("Way mit ID " + way.getId() + " , startnode: " +
+		 * way.getFromNode().getId() + " , EndNode: " + way.getToNode().getId()
+		 * + " wird bearbeitet.");
+		 */
+		// alle Knoten eines ways durchgehen
+		for (int i = 1; i < nodes.length; i++) {
+			// nur wenn der aktuelle Knoten mehr als einen Vorgänger/Nachfolger
+			// hat, wird in die if-Abfrage gesprungen und ein neuer Channel mit
+			//mit dem aktuell betrachtetem Node als Endnode erzeugt
+			if (nodes[i].getPredNodeList().size() > 1 || nodes[i].getSuccNodeList().size() > 1) {
+				tempChannel = createChannel(lastUsedNode, nodes[i], way);
+				// bei Nichteinbahnstraße wird Channel in die andere Richtung
+				// erzeugt
+				if (oneway == false) {
+					createBackChannel(nodes[i], lastUsedNode, way, tempChannel);
+				}
+				lastUsedNode = nodes[i];
+			}
+			// wenn der betrachtete Knoten keine Nachfolger hat, ist ein
+			// Straßenende erreicht. Auch in diesem Fall muß ein Channel erzeugt werden
+			else if (nodes[i].getSuccNodeList().size() == 0) {
+				tempChannel = createChannel(lastUsedNode, nodes[i], way);
+				// Rückrichtung wird nur erzeugt, wenn der OSM-Way keine Einbahnstraße ist
+				if (oneway == false) {
+					createBackChannel(nodes[i], lastUsedNode, way, tempChannel);
+				}
+			}
+			// eine Straße besteht aus 2 Ways, obwohl eigentlich eine reicht
+			// tritt z.b. bei einer brücke auf, brücke wird neuer channel
+			//TODO: kann an dieser stelle das erzeugen von pseudo-channels verhindert werden?
+			//      Idee: speichern eines flags, um diese erzeugten Channels zu markieren. aus diesen informationen
+			//            später den CHannel löschen!!!
+			else if (i == nodes.length - 1
+					&& nodes[i].getSuccNodeList().size() == 1) {
+				// damit ist ein Channel gefunden, und wird mit Werten gefüllt
+				tempChannel = createChannel(lastUsedNode, nodes[i], way);
+				// bei Nichteinbahnstraße wird Channel in die andere Richtung
+				// erzeugt
+				if (oneway == false) {
+					createBackChannel(nodes[i], lastUsedNode, way, tempChannel);
+				}
+				lastUsedNode = nodes[i];
+
+			}
+
+		}
+	}
+
+	/**
+	 * baut den ChannelDigraph
+	 */
+	public void buildChannelDigraph() {
+		// alle Wege eines OSMGraphen durchgehen
+		for (int i = 0; i < osmways.length; i++) {
+			buildChannels(osmways[i], osmways[i].isOneWay());
+		}
+		trchecker = new TurnRestrictionChecker(osmgraph, digraph);
+		trchecker.createLeadsTo();
+		PseudoChannelRemover pcr = new PseudoChannelRemover(digraph); //überflüssige Channels entfernen
+		pcr.removePseudoChannels();
+	}
+
+	public ChannelDiGraph getDigraph() {
+		return digraph;
+	}
+
+	public void setNewid(int newid) {
+		this.newid = newid;
+	}
+
+	public int getNewid() {
+		return newid;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/NodesConnectionProducer.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/NodesConnectionProducer.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/NodesConnectionProducer.java	(revision 25501)
@@ -0,0 +1,33 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.converting;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMNode;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMWay;
+
+/**
+ * NodesConnectionProducer erstellt die Nachbarschaftsbeziehungen der einzelnen OSMNodes eines OSM-Graphen
+ * aus diesen Beziehungen läßt sich der Channel-Digraph produzieren
+ * @author  joerg
+ */
+public class NodesConnectionProducer {
+	
+	private OSMGraph osmgraph;
+	private OSMWay[] osmways;
+
+	public NodesConnectionProducer(OSMGraph osmgraph) {
+		this.osmgraph = osmgraph;
+		osmways = this.osmgraph.getWays();
+	}
+	
+	public void produceNodesConnections() {
+		OSMNode[] waynodes;
+		for (int i = 0; i < osmways.length; i++) {
+			waynodes = osmways[i].getNodes();
+			for (int j = 0; j < waynodes.length - 1; j++) {
+				waynodes[j].addSuccNode(waynodes[j+1]);
+				waynodes[j+1].addPredNode(waynodes[j]);
+			}
+		}
+	}
+
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/PseudoChannelRemover.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/PseudoChannelRemover.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/PseudoChannelRemover.java	(revision 25501)
@@ -0,0 +1,81 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.converting;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
+
+/**
+ * löscht Pseudochannels, also 2 Channels, die ein Segment repräsentieren, werden zu einem Channel zusammnegefaßt. Dabei übernimmt der 1. Channel den ToNode des Nachfrolger sowie seine LeadsTo-Relationen. Der 2. CHannel wird anschließend gelöscht. Dies iterativ bis das betrachtete Segment nur noch aus einem Channel besteht
+ * @author  joerg
+ */
+public class PseudoChannelRemover {
+
+	private final ChannelDiGraph digraph;
+	private final ArrayList<Channel> pseudochannels = new ArrayList<Channel>();
+	private int c = 0;
+	private Channel succChannel;
+	private String s;
+	private Channel tempToChannel;
+	private LeadsTo tempLeadsTo;
+
+	public PseudoChannelRemover(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+	}
+
+	private void mergeChannel(Channel tempchannel) {
+		succChannel = tempchannel.getLeadsTo().get(0).getToChannel();
+		tempchannel.setToNode(succChannel.getToNode());
+		s = "";
+		//log.trace("---Folgender Channel ist überflüssig: " + succChannel.getNewid() + "---");
+		//log.trace("... und wird durch diesen ersetzt: " + tempchannel.getNewid());
+		//VorgängerChannel der nachfolgenden Channels des zu löschenden, überflüssigen Channels neu setzen
+		for (int i = 0; i < succChannel.getLeadsTo().size(); i++) {
+			for (int j = 0; j < succChannel.getLeadsTo().get(i).getToChannel().getPredChannels().size(); j++) {
+				if (succChannel.getLeadsTo().get(i).getToChannel().getPredChannels().get(j).getNewid() == succChannel.getNewid()) {
+					succChannel.getLeadsTo().get(i).getToChannel().getPredChannels().remove(j);
+					succChannel.getLeadsTo().get(i).getToChannel().addPredChannel(tempchannel);
+				}
+			}
+		}
+
+		//LeadsTo des zu ersetzenden Channels für den neuen Channel neu erzeugen
+		tempchannel.removeLeadsTo();
+		for (int i = 0; i < succChannel.getLeadsTo().size(); i++) {
+			tempToChannel = succChannel.getLeadsTo().get(i).getToChannel();
+			//log.trace("tempToChannel: " + tempToChannel.toString());
+			tempLeadsTo = new LeadsTo(tempchannel, tempToChannel);
+			//log.trace(i + ". Durchlauf: Füge ledasTo hinzu: " + tempLeadsTo.toString());
+			digraph.addLeadsTo(tempLeadsTo);
+		}
+
+		//TODO: quick'n'dirty
+		ArrayList< LeadsTo> tls = succChannel.getLeadsTo();
+		for (int i = 0; i < tls.size(); i++) {
+			digraph.removeLeadsTo(tls.get(i));
+		}
+		digraph.removeChannel(succChannel);
+		//pseudochannels.add(tempchannel.getSuccChannels().get(0));
+		c++;
+	}
+
+	public void removePseudoChannels() {
+		Channel tempChannel;
+		for (int i = 0; i < digraph.getChannels().size(); i++) {
+			tempChannel = digraph.getChannelAtPosition(i);
+			while (digraph.isInBBox(tempChannel.getToNode())
+					&& (tempChannel.getLeadsTo().size() == 1)
+					&& (tempChannel.getLeadsTo().get(0).getToChannel().getPredChannels().size() <= 1)
+					&& (tempChannel.getBackChannelID() != tempChannel.getLeadsTo().get(0).getToChannel().getNewid())) {
+				// dies if-abfrage verhindert eine endlosschleife, wenn der
+				// channel ein kreisverkehr istjava
+				if (tempChannel.getLeadsTo().get(0).getToChannel().equals(tempChannel)) {
+					break;
+				} else {
+					mergeChannel(tempChannel);
+				}
+			}
+
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/TurnRestrictionChecker.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/TurnRestrictionChecker.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/converting/TurnRestrictionChecker.java	(revision 25501)
@@ -0,0 +1,118 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.converting;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMRelation;
+
+/**
+ * TurnRestrictionChecke prüft einen OSMGraphen auf vorhandene
+ * Abbiegerestriktionen in den Relationen und paßt die Abiegerestriktionen der
+ * Channels des aus dem OSMGraphen erzeugten ChannelDigraphen dementsprechend
+ * an. wird vom ChannelDigraphBuilder aufgerufen
+ * 
+ * @author Jörg Possin
+ */
+public class TurnRestrictionChecker {
+
+	private final ArrayList<OSMRelation> turnrestrictionsrelations = new ArrayList<OSMRelation>();
+	private final ChannelDiGraph channelDigraph;
+	private final boolean isInturnrestriction;
+	private int relationpointer;
+	private LeadsTo tempLeadsTo;
+
+	public TurnRestrictionChecker(OSMGraph graph, ChannelDiGraph channelDigraph) {
+		// von den Relationen des Graphen nur die Abbiegevorschriften kopieren
+		for (int i = 0; i < graph.getRelations().length; i++) {
+			if (graph.getRelations()[i].hasKey("type")) {
+				if (graph.getRelations()[i].getValue("type").equals(
+				"restriction")) {
+					turnrestrictionsrelations.add(graph.getRelations()[i]);
+				}
+			}
+		}
+		this.channelDigraph = channelDigraph;
+		this.isInturnrestriction = false;
+	}
+
+	private boolean checkForRelations(Channel channel) {
+		for (int k = 0; k < turnrestrictionsrelations.size(); k++) {
+			//log.trace("betrachte relation in liste an position:" + k);
+			for (int i = 0; i < channel.getWays().size(); i++) {
+				if (turnrestrictionsrelations.get(k).getMember("from").getId() == channel
+						.getWays().get(i).getId()
+						&& turnrestrictionsrelations.get(k).getMember("via")
+						.getId() == channel.getToNode().getId()) {
+					relationpointer = k;
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private void produceLeadsToFromRelation(Channel fromChannel,
+			Channel toChannel) {
+		if (toChannel.getWays().contains(
+				turnrestrictionsrelations.get(relationpointer).getMember("to"))) {
+			if (turnrestrictionsrelations.get(relationpointer).getValue(
+			"restriction").startsWith("only")) {
+
+				tempLeadsTo = new LeadsTo(fromChannel, toChannel);
+				channelDigraph.addLeadsTo(tempLeadsTo);
+				toChannel.addPredChannel(fromChannel);
+			}
+			/*
+			 * der no_* Fall: wie oben, nur das hier nichts geschieht
+			 */
+			else if (turnrestrictionsrelations.get(relationpointer).getValue(
+			"restriction").startsWith("no")) {
+				for (int i = 0; i < fromChannel.getToNode()
+				.getOutgoingChannels().size(); i++) {
+					if (fromChannel.getToNode().getOutgoingChannels().get(i) != toChannel) {
+						tempLeadsTo = new LeadsTo(fromChannel, fromChannel
+								.getToNode().getOutgoingChannels().get(i));
+						channelDigraph.addLeadsTo(tempLeadsTo);
+						fromChannel.getToNode().getOutgoingChannels().get(i)
+						.addPredChannel(fromChannel);
+					}
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * startet die LeadsTo Erstellung
+	 */
+	public void createLeadsTo() {
+		Channel tempChannel;
+		for (int i = 0; i < channelDigraph.getChannels().size(); i++) {
+			tempChannel = channelDigraph.getChannelAtPosition(i);
+			boolean isInRelation = checkForRelations(tempChannel);
+			for (int j = 0; j < tempChannel.getToNode().getOutgoingChannels()
+			.size(); j++) {
+				if (isInRelation) {
+					produceLeadsToFromRelation(tempChannel, tempChannel
+							.getToNode().getOutgoingChannels().get(j));
+					// es wird nur dann ein leadsTo erzeugt, wenn der vom
+					// Endknoten des Channels
+					// ausgehende Channel NICHT der Channel in Rückrichtung ist
+					// Ausnahme: es gibt nur diesen einen Channel (Wegende eines
+					// Ways, der an keine weitere
+					// Straße trifft
+				} else if (tempChannel.getBackChannelID() != tempChannel
+						.getToNode().getOutgoingChannels().get(j).getNewid()
+						|| tempChannel.getToNode().getOutgoingChannels().size() == 1) {
+					tempLeadsTo = new LeadsTo(tempChannel, tempChannel
+							.getToNode().getOutgoingChannels().get(j));
+					channelDigraph.addLeadsTo(tempLeadsTo);
+					tempChannel.getToNode().getOutgoingChannels().get(j)
+					.addPredChannel(tempChannel);
+				}
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/BasicChannel.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/BasicChannel.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/BasicChannel.java	(revision 25501)
@@ -0,0 +1,205 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.ArrayList;
+
+/**
+ * BasicChannel hat alle Eigenschaften, die eine Channelklasse für einen DIgrpahen braucht.
+ * @author  joerg
+ */
+public class BasicChannel {
+
+	private OSMNode toNode;
+	private OSMNode fromNode;
+	private ArrayList<LeadsTo> leadsTo = new ArrayList<LeadsTo>();
+	private final ArrayList<OSMWay> ways = new ArrayList<OSMWay>();
+	private int newid;
+	//gibt es nur, wenn ein Channelobjekt aus einer Nichteinbahnstraße erzeugt wurde (backchannelID ist dann die ID des anderen Channels)
+	private int backChannelID = -100;
+	private final ArrayList<Channel> predChannels = new ArrayList<Channel>();
+
+	//werden für den Tarjan-Algorithmus gebraucht
+	private int lowlink = -1;
+	private int index = -1;
+
+	/**
+	 * fügt einen Vorgängerchannel hinzu
+	 * @param channel der voherige Channel
+	 */
+	public void addPredChannel(Channel channel) {
+		predChannels.add(channel);
+	}
+
+	/**
+	 * setzt den ToNode
+	 * @param toNode
+	 */
+	public void setToNode(OSMNode toNode) {
+		this.toNode = toNode;
+	}
+
+	/**
+	 * gbit den ToNode zurück
+	 */
+	public OSMNode getToNode() {
+		return toNode;
+	}
+
+	/**
+	 * setzt den FromNode
+	 */
+	public void setFromNode(OSMNode fromNode) {
+		this.fromNode = fromNode;
+	}
+
+	/**
+	 * gibt den FromNode zurück
+	 */
+	public OSMNode getFromNode() {
+		return fromNode;
+	}
+
+	/**
+	 * fügt eine LeadsTo-Beziehung hinzu
+	 * @param leadsTo
+	 */
+	public void addLeadsTo(LeadsTo leadsTo) {
+		this.leadsTo.add(leadsTo);
+	}
+
+	/**
+	 * setzt alle leadsTo-Beziehungen (löscht alle voherigen)
+	 */
+	public void setLeadsTo(ArrayList<LeadsTo> leadsTo) {
+		this.leadsTo = leadsTo;
+	}
+
+	/**
+	 * löscht alle LeadsTo des Channels
+	 */
+	public void removeLeadsTo() {
+		this.leadsTo.clear();
+	}
+
+	/**
+	 * gibt alle leadsTo zurück
+	 * @return
+	 */
+	public ArrayList<LeadsTo> getLeadsTo() {
+		return leadsTo;
+	}
+
+	/**
+	 * fügt einen Way hinzu, aus dem der Channel enstanden ist
+	 * es gibt immer mind. einen Way, es können aber auch mehr sein
+	 * @param way
+	 */
+	public void addWay(OSMWay way) {
+		this.ways.add(way);
+	}
+
+	/**
+	 * gibt alle Ways zurück
+	 * @return
+	 */
+	public ArrayList<OSMWay> getWays() {
+		return ways;
+	}
+
+	/**
+	 * gibt nur den ersten Way der ArrayList zurück! wird bei der
+	 * XML-datei-Erzeugung benutzt, um den Way, der aus dem Channel entsteht,
+	 * mit Werten zu füllen dabei gehen Informationen verloren, da ein Channel
+	 * aus mehr als einem Way bestehen kann
+	 * 
+	 * @return
+	 */
+	public OSMWay getWay() {
+		return ways.get(0);
+	}
+
+	/**
+	 * setzt die ID des Channels. es kann nicht die ID des Ways übernommen werden, da aus einem Way oftmals mehrere Channels entstehen (z.B. bei jeder Nichteinbahnstraße mind. 2)
+	 */
+	public void setNewid(int newid) {
+		this.newid = newid;
+	}
+
+	/**
+	 * gbit die NewID zurück
+	 */
+	public int getNewid() {
+		return newid;
+	}
+
+	/**
+	 * gibt alle VorgängerChannels zurück
+	 * @return
+	 */
+	public ArrayList<Channel> getPredChannels() {
+		return predChannels;
+	}
+
+	/**
+	 * ToString Methode
+	 */
+	@Override
+	public String toString() {
+		String lt ="";
+		for (int i = 0; i < leadsTo.size(); i++) {
+			lt += leadsTo.get(i).getToChannel().getNewid() + ", ";
+		}
+		String predch = "";
+		for (int i = 0; i < predChannels.size(); i++) {
+			predch += predChannels.get(i).getNewid() + ", ";
+		}
+		return "[ChannelID: "+ newid + ":AnzahlPredCH: " + predChannels.size() + ":PredCh: " + predch +  ":AnzahlSuccCH: " + leadsTo.size() +":LeadsTo: " + lt+ ":backCHID: " + backChannelID + "]";
+	}
+
+	public void setBackChannelID(int backChannelID) {
+		this.backChannelID = backChannelID;
+	}
+
+	public int getBackChannelID() {
+		return backChannelID;
+	}
+
+	/**
+	 * wandelt den Channel in einen OSMWay um
+	 * dabie werden die Werte des 1. Way, der im Channel ist, übernommen, wenn ein
+	 * 1. Channel existiert
+	 */
+	public OSMWay ToOSMWay() {
+		OSMWay way = new OSMWay();
+		way.addNode(this.fromNode);
+		way.addNode(this.toNode);
+		way.setId((long)this.newid);
+		if (this.getWay() != null) {
+			way.setHashmap(this.getWay().getHashmap());
+		}
+		return way;
+	}
+
+	public void ereasePredChannel(Channel rchannel) {
+		predChannels.remove(rchannel);
+	}
+
+	public int getLowlink() {
+		return lowlink;
+	}
+
+	public void setLowlink(int lowlink) {
+		this.lowlink = lowlink;
+	}
+
+	public int getIndex() {
+		return index;
+	}
+
+	public void setIndex(int index) {
+		this.index = index;
+	}
+
+	public void removeLeadsTo(LeadsTo leadsTo) {
+		this.leadsTo.remove(leadsTo);
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/Channel.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/Channel.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/Channel.java	(revision 25501)
@@ -0,0 +1,240 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.connectedness.BacktrackingColors;
+
+/**
+ * Diese Klasse erweitert BasicChannel um die Dinge, die für die Kreuzungsalgorithmen benötigt werden
+ * @author  joerg
+ */
+public class Channel extends BasicChannel{
+
+	//für den Junctioncheck
+	private int indegree;
+	private int outdegree;
+	private boolean subgraph;
+	private int visited = BacktrackingColors.WHITE;
+	private final ArrayList<Channel> reachableNodes = new ArrayList<Channel>();
+	private int ennr;
+	private boolean isStrongConnected = true;
+	private boolean isSelected = false; //wird für den eigenen Layer benötigt, um markierte Channels zu erhalten
+	private boolean isPartOfJunction = false; //wird für den eigenen Layer benötigt, um Teile einer Kreuzung farbig repräsentieren zu können
+	
+	private final HashMap<Channel , ArrayList<Channel>> paths2 = new HashMap<Channel , ArrayList<Channel>>();
+
+
+	public Channel(OSMNode fromNode, OSMNode toNode) {
+		super();
+		this.setFromNode(fromNode);
+		this.setToNode(toNode);
+		this.subgraph = false;
+		this.indegree = 0;
+		this.outdegree = 0;
+	}
+
+	public Channel(){
+		super();
+		//this.insidenodes = new ArrayList<OSMNode>();
+		this.subgraph = false;
+		this.indegree = 0;
+		this.outdegree = 0;
+	}
+
+	/**
+	 * gibt die Anzahl der auf diesen Channel verweisenden leadsTo zurück
+	 * @return
+	 */
+	public int getIndegree() {
+		return indegree;
+	}
+
+	/**
+	 * gibt die Anzahl der aus diesem Channel gehenden leadsTo zurück
+	 * @return
+	 */
+	public int getOutdegree() {
+		return outdegree;
+	}
+
+	public void setIndegree(int i) {
+		this.indegree = i;
+	}
+
+	public void setOutdegree(int i){
+		this.outdegree = i;
+	}
+
+	/**
+	 * ist dieser Channel Teil der zu untersuchenden Kreuzung?
+	 */
+	public boolean isSubgraph() {
+		return subgraph;
+	}
+
+	public void setSubgraph(boolean subgraph) {
+		this.subgraph = subgraph;
+	}
+
+	/**
+	 * setzt die Farbe des Channels für den TRDFS white = unbesucht grey = besucht, aber noch nicht beendet black = besucht nund abgeschlossen
+	 */
+	public int getVisited() {
+		return visited;
+	}
+
+	public void setVisited(int visited) {
+		this.visited = visited;
+	}
+
+	/**
+	 * gibt die von diesem Channel zu erreichenden anderen CHannels zurück
+	 * @return
+	 */
+	public ArrayList<Channel> getReachableNodes() {
+		return reachableNodes;
+	}
+
+	/**
+	 * setzt die zu erreichenden Channels alle anderen werden gelöscht
+	 * @param  reachableNodes
+	 */
+	public int getEnnr() {
+		return ennr;
+	}
+
+	/**
+	 * setzt die Anzahl der EingangsChannel
+	 * @param  ennr
+	 */
+	public void setEnnr(int ennr) {
+		this.ennr = ennr;
+	}
+
+	/**
+	 * erhöht den Wert der Anzhal der EingangsledasTo um 1
+	 */
+	public void countupIndegree() {
+		indegree++;
+	}
+
+	/**
+	 * erhöht den Wert der Anzahl der AusgangsleadsTo um 1
+	 */
+	public void countupOutdegree() {
+		outdegree++;
+	}
+
+	/**
+	 * fügt einen erreichbaren Channel hinzu
+	 * @param node
+	 */
+	public void addReachableNode(Channel node) {
+		if (!reachableNodes.contains(node)) {
+			reachableNodes.add(node);
+			paths2.put(node, new ArrayList<Channel>());
+		}
+	}
+
+	/**
+	 * gibt den an der Position i gespeicherten erreichbaren Channel zurück
+	 * @param i
+	 * @return
+	 */
+	public Channel getReachableNodeAt(int i) {
+		return reachableNodes.get(i);
+	}
+
+	/**
+	 * löscht alle erreichbaren Channels
+	 */
+	public void ereaseReachableNodes() {
+		reachableNodes.clear();
+	}
+
+	/**
+	 * setzt Wert der erreichbaren Eingangschannel auf 0
+	 */
+	public void setEnnrZero() {
+		ennr = 0;
+	}
+
+	/**
+	 * erhöht den Wert der Eingänge um 1
+	 */
+	public void increaseEnnr() {
+		ennr++;
+	}
+
+
+	/**
+	 * fügt einen Pfad den Pfaden zu
+	 * @param path
+	 */
+	public void appendPath(Channel node, ArrayList<Channel> path) {
+		for (int i = 0; i < path.size(); i++) {
+			if (!paths2.get(node).contains(path.get(i))) {
+				paths2.get(node).add(path.get(i));
+			}
+		}
+	}
+
+	public void appendChannelToPath(Channel node, Channel channel) {
+		if (!paths2.containsKey(node)) {
+			paths2.put(node, new ArrayList<Channel>());
+
+		}
+		if (!paths2.get(node).contains(channel)) {
+			paths2.get(node).add(channel);
+
+		}
+	}
+
+	/**
+	 * gibt alle Pfade zurück
+	 * @return
+	 */
+	public ArrayList<ArrayList<Channel>> getPaths() {
+		ArrayList<ArrayList<Channel>> t = new ArrayList<ArrayList<Channel>>();
+		t.addAll(paths2.values());
+		return t;
+	}
+
+	public ArrayList<Channel> getPathsAt(Channel node) {
+		if (paths2.containsKey(node)) {
+			return paths2.get(node);
+		}
+		else {
+			//log.error("das darf nicht bei Channel: " + this.getNewid() + ", kein Node " + node.getNewid());
+			return null;
+		}
+
+	}
+
+	public boolean isStrongConnected() {
+		return isStrongConnected;
+	}
+
+	public void setStrongConnected(boolean isStrongConnected) {
+		this.isStrongConnected = isStrongConnected;
+	}
+
+	public boolean isSelected() {
+		return isSelected;
+	}
+
+	public void setSelected(boolean isSelected) {
+		this.isSelected = isSelected;
+	}
+
+	public boolean isPartOfJunction() {
+		return isPartOfJunction;
+	}
+
+	public void setPartOfJunction(boolean isPartOfJunction) {
+		this.isPartOfJunction = isPartOfJunction;
+	}
+
+	
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/ChannelDiGraph.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/ChannelDiGraph.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/ChannelDiGraph.java	(revision 25501)
@@ -0,0 +1,335 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+
+/**
+ * @author  joerg
+ */
+public class ChannelDiGraph extends Graph {
+
+	private ArrayList<Channel> channels = new ArrayList<Channel>();
+	private final ArrayList<LeadsTo> leadsTos = new ArrayList<LeadsTo>();
+	private final HashSet<Channel> selectedChannels = new HashSet<Channel>();
+	private HashSet<Channel> junctioncandidate = new HashSet<Channel>();
+
+	public void setChannels(ArrayList<Channel> channels) {
+		this.channels = channels;
+	}
+
+	/*
+	 * gibt den Channel mit dem übergebendem OSMNode als FromNode zurück
+	 */
+	public Channel getChannelWithFromNode(OSMNode node) {
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).getFromNode() == node) {
+				return channels.get(i);
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * gibt alle CHannels des Digraphen zurück
+	 * @return  Channels des Digraphen
+	 */
+	public ArrayList<Channel> getChannels() {
+		return channels;
+	}
+
+	/**
+	 * löscht den übergebenden Channel im Digraphen
+	 * 
+	 * @param channel
+	 */
+	public void removeChannel(Channel channel) {
+		channels.remove(channel);
+	}
+
+	/**
+	 * fügt einen Channel des ChannelDigraphen hinzu
+	 * 
+	 * @param channel
+	 *            hinzuzufügender Channel
+	 */
+	public void addChannel(Channel channel) {
+		this.channels.add(channel);
+	}
+
+	/**
+	 * Anzahl der innerhalb des DiGraphen gespeicherten Channels
+	 * 
+	 * @return Anzahl der Channels
+	 */
+	public int numberOfChannels() {
+		return channels.size();
+	}
+
+	/**
+	 * gibt Channel i an der Position i in der ArrayList zurück
+	 * 
+	 * @param i
+	 *            Position innerhalb der ArrayList
+	 * @return gewünschter Channel
+	 */
+	public Channel getChannelAtPosition(int i) {
+		return channels.get(i);
+	}
+
+	/**
+	 * gibt den Channel mit der gesuchten ID zurück
+	 * @param id ID des Channels
+	 * @return der gesuchte Channel, wenn nicht vorhanden null
+	 */
+	public Channel getChannelWithID(int id) {
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).getNewid() == id) {
+				return channels.get(i);
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * gibt alle From und To OSMNodes eines Graphen zurück (nicht die
+	 * ZWischenknoten)
+	 * 
+	 * @return alle From und To Nodes aller Channels des Digraphen
+	 */
+	public OSMNode[] getAllOSMNodes() {
+		HashMap<Long, OSMNode> nodes = new HashMap<Long, OSMNode>();
+		for (int i = 0; i < channels.size(); i++) {
+			if (!nodes.containsKey(channels.get(i).getFromNode().getId())) {
+				nodes.put(channels.get(i).getFromNode().getId(), channels
+						.get(i).getFromNode());
+			}
+			if (!nodes.containsKey(channels.get(i).getToNode().getId())) {
+				nodes.put(channels.get(i).getToNode().getId(), channels.get(i)
+						.getToNode());
+			}
+		}
+		OSMNode[] nodearray = new OSMNode[nodes.size()];
+		return nodes.values().toArray(nodearray);
+	}
+
+	public ArrayList<LeadsTo> getLeadsTo() {
+		return leadsTos;
+	}
+
+	/*
+	public void setLeadsTo(ArrayList<LeadsTo> leadsTo) {
+		this.leadsTos = leadsTo;
+	}*/
+
+	public void setForwardEdge(Channel fromChannel, Channel toChannel) {
+		for (int i = 0; i < leadsTos.size(); i++) {
+			if (leadsTos.get(i).getFromChannel() == fromChannel) {
+				if (leadsTos.get(i).getToChannel() == toChannel)
+					leadsTos.get(i).setForwardEdge(true);
+			}
+		}
+
+	}
+
+	/**
+	 * fügt eine leadsto-relation dem digraphen und dem entsprechendem Channel hinzu
+	 * @param leadsTo
+	 */
+	public void addLeadsTo(LeadsTo leadsTo) {
+		leadsTos.add(leadsTo);
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).getNewid() == leadsTo.getFromChannel().getNewid()) {
+				channels.get(i).addLeadsTo(leadsTo);
+				return;
+			}
+		}
+	}
+
+	public void removeLeadsTo(LeadsTo leadsTo) {
+		leadsTos.remove(leadsTo);
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).equals(leadsTo.getFromChannel())) {
+				channels.get(i).removeLeadsTo(leadsTo);
+				return;
+			}
+		}
+	}
+
+	/**
+	 * gibt den Channel zurück, der paßt. Sind Channel doppelt vorhanden, wird
+	 * nur der erste passende zurückgegeben!
+	 * 
+	 * @param fromChannel
+	 * @param toChannel
+	 * @return
+	 */
+	public LeadsTo getLeadsTo(Channel fromChannel, Channel toChannel) {
+		for (int i = 0; i < leadsTos.size(); i++) {
+			if (leadsTos.get(i).getFromChannel().getNewid() == fromChannel.getNewid()) {
+				//log.trace("FromChannel mit ID gefunden: " + fromChannel.getNewid());
+				if (leadsTos.get(i).getToChannel().getNewid() == toChannel.getNewid()) {
+					//log.trace("Leads To gefunden: " + leadsTos.get(i).toString());
+					return leadsTos.get(i);
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * gibt alle Channels zurück, die von diesen OSM-Knoten abgehen/hingehen
+	 * @param nodes
+	 * @return
+	 */
+	public ArrayList<Channel> getChannelsTouchingOSMNodes (ArrayList<OSMNode> nodes) {
+		ArrayList<Channel> touchingChannel = new ArrayList<Channel>();
+		for (int i = 0; i < nodes.size(); i++) {
+			for (int j = 0; j < channels.size(); j++) {
+				if (channels.get(j).getFromNode().getId() == nodes.get(i).getId()) {
+					if (!touchingChannel.contains(channels.get(j))) {
+						touchingChannel.add(channels.get(j));
+					}
+				}
+				else if (channels.get(j).getToNode().getId() == nodes.get(i).getId()) {
+					if (!touchingChannel.contains(channels.get(j))) {
+						touchingChannel.add(channels.get(j));
+					}
+				}
+			}
+		}
+		return touchingChannel;
+	}
+
+	public ArrayList<Channel> getChannelsTouchingOSMNode(long id) {
+		ArrayList<Channel> returnchannels = new ArrayList<Channel>();
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).getFromNode().getId() == id) {
+				returnchannels.add(channels.get(i));
+			}
+			if (channels.get(i).getToNode().getId() == id) {
+				returnchannels.add(channels.get(i));
+			}
+		}
+		return returnchannels;
+	}
+
+	/**
+	 * gibt den oder die Channels twischen diesen OSM-Punkten zurück
+	 * @param idfrom
+	 * @param idto
+	 * @return
+	 */
+	public ArrayList<Channel> getChannelsBetween(int idfrom, int idto) {
+		ArrayList<Channel> channelsresult = new ArrayList<Channel>();
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).getFromNode().getId() == idfrom) {
+				if (channels.get(i).getToNode().getId() == idto) {
+					channelsresult.add(channels.get(i));
+				}
+			}
+			else if (channels.get(i).getFromNode().getId() == idto) {
+				if (channels.get(i).getToNode().getId() == idfrom) {
+					channelsresult.add(channels.get(i));
+				}
+			}
+		}
+		return channelsresult;
+	}
+
+	public ArrayList<Channel> getChannelswithWayID(int id) {
+		ArrayList<Channel> channelsresult = new ArrayList<Channel>();
+		for (int i = 0; i < channels.size(); i++) {
+			if (channels.get(i).getWay().getId() == id) {
+				channelsresult.add(channels.get(i));
+			}
+		}
+		return channelsresult;
+	}
+
+	public void detectSelectedChannels(double left, double top, double right, double bottom) {
+		for (int i = 0; i < channels.size(); i++) {
+			//log.trace(channels.get(i).getFromNode().toString());
+			if ( (channels.get(i).getFromNode().getLatitude() <= top) && (channels.get(i).getFromNode().getLatitude() >= bottom)
+					&& (channels.get(i).getFromNode().getLongitude() >= left) && (channels.get(i).getFromNode().getLongitude() <=right)) {
+				channels.get(i).setSelected(true);
+				selectedChannels.add(channels.get(i));
+			}
+			if ( (channels.get(i).getToNode().getLatitude() <= top) && (channels.get(i).getToNode().getLatitude() >= bottom)
+					&& (channels.get(i).getToNode().getLongitude() >= left) && (channels.get(i).getToNode().getLongitude() <=right)) {
+				channels.get(i).setSelected(true);
+				selectedChannels.add(channels.get(i));
+			}
+		}
+	}
+
+	/**
+	 * löscht die markierten Channels aus der Liste der markierten Channels und setzt die
+	 * Eigenschaft isSelected auf false
+	 */
+	public void ereaseSelectedChannels() {
+		for (int i = 0; i < selectedChannels.size(); i++) {
+			Iterator<Channel> it = selectedChannels.iterator();
+			while (it.hasNext()) {
+				it.next().setSelected(false);
+			}
+		}
+		selectedChannels.clear();
+	}
+
+	public HashSet<Channel> getSelectedChannels() {
+		return selectedChannels;
+	}
+
+	public HashSet<Channel> getJunctionCandidate() {
+		return junctioncandidate;
+	}
+
+	public void ereaseJunctioncandidate() {
+		Iterator<Channel> it = junctioncandidate.iterator();
+		while (it.hasNext()) {
+			it.next().setPartOfJunction(false);
+		}
+		junctioncandidate.clear();
+	}
+
+	/**
+	 * setzt die Channels eines Kreuzungskandidaten
+	 * falls in im Hashset vorher Channels gespeichert waren, werden diese vorher gelöscht!
+	 * @param junctionCandidate
+	 */
+	public void setJunctioncandidate(HashSet<Channel> junctionCandidate) {
+		this.junctioncandidate.clear();
+		this.junctioncandidate = junctionCandidate;
+		Iterator<Channel> it = junctionCandidate.iterator();
+		while (it.hasNext()) {
+			it.next().setPartOfJunction(true);
+		}
+	}
+
+	public void addJunctioncandidateChannel(Channel channel) {
+		junctioncandidate.add(channel);
+		channel.setPartOfJunction(true);
+	}
+
+	/*TODO: kann weg oder?
+	public void ereaseChannelsSubgraph() {
+		for (int i = 0; i < channels.size(); i++) {
+			channels.get(i).setSubgraph(false);
+		}
+	}
+
+	public void ereaseChannelsInDegree() {
+		for (int i = 0; i < channels.size(); i++) {
+			channels.get(i).setIndegree(0);
+		}
+	}
+
+	public void ereaseChannelsOutDegree() {
+		for (int i = 0; i < channels.size(); i++) {
+			channels.get(i).setOutdegree(0);
+		}
+	}
+	 */
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/Graph.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/Graph.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/Graph.java	(revision 25501)
@@ -0,0 +1,50 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+/**
+ * @author  joerg
+ */
+public class Graph {
+	
+	//Boundingbox
+	private double bbleft;
+	private double bbright;
+	private double bbbottom;
+	private double bbtop;
+	
+	
+	public double getBbleft() {
+		return bbleft;
+	}
+	public void setBbleft(double bbleft) {
+		this.bbleft = bbleft;
+	}
+	public double getBbright() {
+		return bbright;
+	}
+	public void setBbright(double bbright) {
+		this.bbright = bbright;
+	}
+	public double getBbbottom() {
+		return bbbottom;
+	}
+	public void setBbbottom(double bbbottom) {
+		this.bbbottom = bbbottom;
+	}
+	public double getBbtop() {
+		return bbtop;
+	}
+	public void setBbtop(double bbtop) {
+		this.bbtop = bbtop;
+	}
+	public boolean isInBBox(OSMNode node) {
+		if ( (node.getLatitude() <= bbtop) && (node.getLatitude() >= bbbottom)
+				&& (node.getLongitude() >= bbleft) && (node.getLongitude() <=bbright)) {
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+	
+	
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/LeadsTo.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/LeadsTo.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/LeadsTo.java	(revision 25501)
@@ -0,0 +1,52 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+/**
+ * @author  joerg
+ */
+public class LeadsTo {
+
+	private Channel fromChannel;
+	private Channel toChannel;
+
+	//für den JunctionCheck
+	private boolean isForwardEdge;
+
+	public LeadsTo() {
+	}
+
+	public LeadsTo(Channel fromcChannel, Channel toChannel) {
+		this.fromChannel = fromcChannel;
+		this.toChannel = toChannel;
+	}
+
+	public Channel getFromChannel() {
+		return fromChannel;
+	}
+
+	public void setFromChannel(Channel fromChannel) {
+		this.fromChannel = fromChannel;
+	}
+
+	public Channel getToChannel() {
+		return toChannel;
+	}
+
+	public void setToChannel(Channel toChannel) {
+		this.toChannel = toChannel;
+	}
+
+	public boolean isForwardEdge() {
+		return isForwardEdge;
+	}
+
+	public void setForwardEdge(boolean isForwardEdge) {
+		this.isForwardEdge = isForwardEdge;
+	}
+
+	@Override
+	public String toString() {
+		return "fromChannel:::" + fromChannel.getNewid()  + ", toChannel:::" + toChannel.getNewid() + " über Node " + toChannel.getFromNode().getId();
+	}
+
+
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMEntity.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMEntity.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMEntity.java	(revision 25501)
@@ -0,0 +1,177 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.HashMap;
+
+/**
+ * Basisklasse für die 3 OSM-Objekte Node, Way und Relation
+ * @author  joerg
+ */
+public class OSMEntity {
+	
+	//TODO Idee: alle Wertestandardmäßig auf -1 setzen, so muß
+	//man bei der Umwandlung nicht auf null-Werte prüfen
+	/**
+	 * @uml.property  name="id"
+	 */
+	private long id;
+	/**
+	 * @uml.property  name="visible"
+	 */
+	private boolean visible;
+	/**
+	 * @uml.property  name="timestamp"
+	 */
+	private String timestamp;
+	/**
+	 * @uml.property  name="user"
+	 */
+	private String user;
+	/**
+	 * @uml.property  name="uid"
+	 */
+	private int uid;
+	/**
+	 * @uml.property  name="changeset"
+	 */
+	private int changeset;
+	/**
+	 * @uml.property  name="hashmap"
+	 */
+	private HashMap<String, String> hashmap = new HashMap<String, String>();
+	/**
+	 * @uml.property  name="version"
+	 */
+	private int version;
+	
+	public void setversion(int version) {
+		this.version = version;
+	}
+	
+	/**
+	 * @return
+	 * @uml.property  name="version"
+	 */
+	public int getVersion() {
+		return version;
+	}
+	
+	/**
+	 * @return
+	 * @uml.property  name="id"
+	 */
+	public long getId() {
+		return id;
+	}
+	public void setId(Long id) {
+		this.id = id;
+	}
+	/**
+	 * @return
+	 * @uml.property  name="visible"
+	 */
+	public boolean isVisible() {
+		return visible;
+	}
+	/**
+	 * @param visible
+	 * @uml.property  name="visible"
+	 */
+	public void setVisible(boolean visible) {
+		this.visible = visible;
+	}
+	/**
+	 * @return
+	 * @uml.property  name="timestamp"
+	 */
+	public String getTimestamp() {
+		return timestamp;
+	}
+	/**
+	 * @param timestamp
+	 * @uml.property  name="timestamp"
+	 */
+	public void setTimestamp(String timestamp) {
+		this.timestamp = timestamp;
+	}
+	/**
+	 * @return
+	 * @uml.property  name="user"
+	 */
+	public String getUser() {
+		return user;
+	}
+	/**
+	 * @param user
+	 * @uml.property  name="user"
+	 */
+	public void setUser(String user) {
+		this.user = user;
+	}
+	/**
+	 * @return
+	 * @uml.property  name="uid"
+	 */
+	public int getUid() {
+		return uid;
+	}
+	/**
+	 * @param uid
+	 * @uml.property  name="uid"
+	 */
+	public void setUid(int uid) {
+		this.uid = uid;
+	}
+	/**
+	 * @return
+	 * @uml.property  name="changeset"
+	 */
+	public int getChangeset() {
+		return changeset;
+	}
+	/**
+	 * @param changeset
+	 * @uml.property  name="changeset"
+	 */
+	public void setChangeset(int changeset) {
+		this.changeset = changeset;
+	}
+	/**
+	 * @return
+	 * @uml.property  name="hashmap"
+	 */
+	public HashMap<String, String> getHashmap() {
+		return hashmap;
+	}
+	/**
+	 * @param hashmap
+	 * @uml.property  name="hashmap"
+	 */
+	public void setHashmap(HashMap<String, String> hashmap) {
+		this.hashmap = hashmap;
+	}
+	
+	public void setKeyValue(String key, String value){
+		hashmap.put(key, value);
+	}
+	
+	public String getValue(String key){
+		return hashmap.get(key);
+	}
+
+	public boolean hasKey(String key){
+		return hashmap.containsKey(key);
+	}
+	
+	/**
+	 * prüft, ob der übergebene String als Wert existiert
+	 * @param value
+	 * @return
+	 */
+	public boolean hasValue(String value){
+		return hashmap.containsValue(value);
+	}
+	
+	protected String valuestoString() {
+		return ("ID: " + (id) + "\n" + "User: " + user + "\n");
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMGraph.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMGraph.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMGraph.java	(revision 25501)
@@ -0,0 +1,130 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+
+
+/**
+ * @author  joerg
+ */
+public class OSMGraph extends Graph{
+
+	private final HashMap<Long, OSMWay> ways = new HashMap<Long, OSMWay>();
+	private HashMap<Long, OSMRelation> relations = new HashMap<Long, OSMRelation>();
+	private final HashMap<Long, OSMNode> nodes = new HashMap<Long, OSMNode>();
+
+	public void addNode(OSMNode node) {
+		nodes.put(node.getId(), node);
+	}
+
+	/**
+	 * gibt den Knoten mit der gesuchten OSM-ID zurück
+	 * @param id OSM-iD des Knotens!
+	 * @return
+	 */
+	public OSMNode getNode(long id) {
+		return nodes.get(id);
+	}
+
+	public void removeWay(OSMWay way) {
+		ways.remove(way);
+	}
+
+	public OSMNode[] getNodes(){
+		OSMNode[] nodearray= new OSMNode[nodes.size()];
+		return nodes.values().toArray(nodearray);
+	}
+
+	public void addWay(OSMWay way) {
+		ways.put(way.getId(), way);
+	}
+
+	public OSMWay getWay(long id) {
+		return ways.get(id);
+	}
+
+	public OSMRelation getRelation(int id) {
+		return relations.get(id);
+	}
+
+	public  HashMap<Long, OSMRelation> getRelationsAshashmap() {
+		return relations;
+	}
+
+	public void setRelations( HashMap<Long, OSMRelation> relations) {
+		this.relations = relations;
+	}
+
+	public OSMWay[] getWays() {
+		OSMWay[] wayarray= new OSMWay[ways.size()];
+		return ways.values().toArray(wayarray);
+	}
+
+	public void addRelation(OSMRelation relation) {
+		relations.put(relation.getId(), relation);
+	}
+
+	public OSMRelation[] getRelations(){
+		OSMRelation[] relationarray = new OSMRelation[relations.size()];
+		return relations.values().toArray(relationarray);
+	}
+
+	public Collection<OSMRelation> getRelationsCollection() {
+		return relations.values();
+	}
+
+	public boolean hasNode(Long id) {
+		return nodes.containsKey(id);
+	}
+
+	public ArrayList<Long> getIDsfromWay(int id) {
+		OSMWay w = ways.get(id);
+		ArrayList<Long> ids  = new ArrayList<Long>();
+		ids.add(w.getToNode().getId());
+		ids.add(w.getFromNode().getId());
+		return ids;
+	}
+
+	public void addNode(Node node) {
+		OSMNode OSMnode = new OSMNode();
+		OSMnode.setId(node.getId());
+		OSMnode.setLatitude(node.getBBox().getTopLeft().lat());
+		OSMnode.setLongitude(node.getBBox().getTopLeft().lon());
+		OSMnode.setHashmap(new HashMap<String, String>(node.getKeys()));
+		nodes.put(OSMnode.getId(), OSMnode);
+	}
+
+	public void addWay(Way way) {
+		OSMWay osmway = new OSMWay();
+		osmway.setId(way.getId());
+		Iterator<Node> it = way.getNodes().iterator();
+		while (it.hasNext()) {
+			osmway.addNode(getNode(it.next().getId()));
+		}
+		osmway.setHashmap(new HashMap<String, String>(way.getKeys()));
+		ways.put(osmway.getId(), osmway);
+	}
+
+	public void addRelation(Relation relation) {
+		OSMRelation osmrelation = new OSMRelation();
+		osmrelation.setId(relation.getId());
+		osmrelation.setHashmap(new HashMap<String, String>(relation.getKeys()));
+		RelationMember rmember;
+		for (int i = 0; i < relation.getMembers().size(); i++) {
+			rmember = relation.getMember(i);
+			if (rmember.getMember() instanceof Node) {
+				osmrelation.addMember(getNode(rmember.getMember().getId()), rmember.getRole());
+			}
+			else if (rmember.getMember() instanceof Way) {
+				osmrelation.addMember(getWay(rmember.getMember().getId()), rmember.getRole());
+			}
+		}
+		relations.put(osmrelation.getId(), osmrelation);
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMNode.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMNode.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMNode.java	(revision 25501)
@@ -0,0 +1,60 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.ArrayList;
+
+
+/**
+ * @author  joerg
+ */
+public class OSMNode extends OSMEntity {
+	
+	private double latitude;
+	private double longitude;
+	private ArrayList<Channel> outgoingChannels = new ArrayList<Channel>();
+	private ArrayList<OSMNode> succNodeList = new ArrayList<OSMNode>();
+	private ArrayList<OSMNode> predNodeList = new ArrayList<OSMNode>();
+	
+	public void addOutgoingChannel(Channel channel) {
+		outgoingChannels.add(channel);
+	}
+	
+	public ArrayList<Channel> getOutgoingChannels() {
+		return outgoingChannels;
+	}
+	
+	public double getLatitude() {
+		return latitude;
+	}
+	public void setLatitude(double latitude) {
+		this.latitude = latitude;
+	}
+	public double getLongitude() {
+		return longitude;
+	}
+	public void setLongitude(double longitude) {
+		this.longitude = longitude;
+	}
+	
+	public String toString(){
+		return valuestoString() + "Lat: " + latitude + "\n" + "Lon: " + longitude;
+	}
+
+	public ArrayList<OSMNode> getSuccNodeList() {
+		return succNodeList;
+	}
+
+	public ArrayList<OSMNode> getPredNodeList() {
+		return predNodeList;
+	}
+	
+	public void addSuccNode(OSMNode node) {
+		succNodeList.add(node);
+	}
+	
+	public void addPredNode(OSMNode node) {
+		predNodeList.add(node);
+	}
+	
+	
+	
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMRelation.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMRelation.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMRelation.java	(revision 25501)
@@ -0,0 +1,90 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.ArrayList;
+
+
+/**
+ * @author  joerg
+ */
+public class OSMRelation extends OSMEntity {
+
+	private ArrayList<Member> members = new ArrayList<Member>();
+
+	public void setMembers(ArrayList<Member> members) {
+		this.members = members;
+	}
+
+	public ArrayList<Member> getMembers() {
+		return members;
+	}
+	
+	/**
+	 * gibt den Member mit der Rolle zurück, wenn vorhanden. Sonst null
+	 * @param role
+	 * @return
+	 */
+	public OSMEntity getMember(String role) {
+		for (int i = 0; i < members.size(); i++) {
+			if (members.get(i).getRole().equals(role)) {
+				return members.get(i).getMember();
+			}
+		}
+		return null;
+	}
+	
+	public void addMember(OSMEntity member, String role) {
+		members.add(new Member(member, role));
+	}
+	
+	public String getRelationType(String key) {
+		return this.getValue(key);
+	}
+	
+	public String toString() {
+		String s = ("Relation-ID: " + this.getId() + " Relation-Type: " + this.getRelationType("type") +"\n");
+		for (int i = 0; i < members.size(); i++) {
+			s += ("Member: " + members.get(i).getRole() + ", ref:" + members.get(i).getId() + ", type:" + members.get(i).getType().getClass().getName() );
+		}
+		return s;
+	}
+	
+
+	/**
+	 * Klasse dient zum Verwalten eines Member-Objektes. Muß ein Objekt vom Typ OSMEntitysein.
+	 * @author  joerg
+	 */
+	class Member {
+
+		private OSMEntity member;
+		private String role;
+
+		public Member(OSMEntity member, String role) {
+			this.member = member;
+			this.setRole(role);
+		}
+		
+		public Class getType() {
+			return member.getClass();
+		}
+
+		public void setMember(OSMEntity member) {
+			this.member = member;
+		}
+
+		public OSMEntity getMember() {
+			return member;
+		}
+
+		public Long getId() {
+			return member.getId();
+		}
+
+		public void setRole(String role) {
+			this.role = role;
+		}
+
+		public String getRole() {
+			return role;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMWay.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMWay.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/datastructure/OSMWay.java	(revision 25501)
@@ -0,0 +1,62 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.datastructure;
+
+import java.util.Vector;
+
+/**
+ * @author joerg
+ */
+public class OSMWay extends OSMEntity {
+
+	private Vector<OSMNode> nodes = new Vector<OSMNode>();
+
+	public OSMNode[] getNodes() {
+		OSMNode[] nodearray = new OSMNode[nodes.size()];
+		return (OSMNode[]) nodes.toArray(nodearray);
+	}
+
+	public OSMNode getToNode() {
+		return nodes.lastElement();
+	}
+
+	public OSMNode getFromNode() {
+		return nodes.firstElement();
+	}
+
+	public void addNode(OSMNode node) {
+		nodes.add(node);
+	}
+
+	public String tosString() {
+		System.out.println(this.getId());
+		return this.valuestoString() + "fromNodeID: "
+				+ this.getFromNode().getId() + "\ntoNodeID: "
+				+ this.getToNode().getId();
+	}
+
+	/**
+	 * ist der OSMWay eine Einbahnstraße?
+	 * 
+	 * @return true wenn ja, sonst nein
+	 */
+	public boolean isOneWay() {
+		// TODO Tippfehler berücksichtigen
+		// evtl. doch über ein XML-File konfigurieren?
+		if (this.hasKey("oneway")) {
+			String t = this.getValue("oneway");
+			if (t.equals("1") || t.equals("true") || t.equals("yes")) {
+				return true;
+			}
+		}
+		String t = this.getValue("highway");
+		if (t != null) {
+			if (t.equals("motorway") || t.equals("motorway_link")) {
+				return true;
+			}
+
+			else {
+				return false;
+			}
+		} else
+			return false;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/filter/ExecuteFilter.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/filter/ExecuteFilter.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/filter/ExecuteFilter.java	(revision 25501)
@@ -0,0 +1,90 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.filter;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMWay;
+import org.openstreetmap.josm.plugins.JunctionChecker.reader.XMLFilterReader;
+
+/**
+ * @author  joerg
+ */
+public class ExecuteFilter {
+	
+	private Filter[] filter;
+	private XMLFilterReader xmlfilterreader;
+	private OSMGraph incominggraph;
+	private OSMGraph outgoinggraph;
+	
+	public ExecuteFilter(Filter[] filter, OSMGraph incoming){
+		this.filter = filter;
+		this.incominggraph = incoming;
+		outgoinggraph = new OSMGraph();
+		outgoinggraph.setBbbottom(incoming.getBbbottom());
+		outgoinggraph.setBbleft(incoming.getBbleft());
+		outgoinggraph.setBbright(incoming.getBbright());
+		outgoinggraph.setBbtop(incoming.getBbtop());
+		outgoinggraph.setRelations(incoming.getRelationsAshashmap());
+	}
+	
+	public ExecuteFilter() {
+	}
+	
+	public void filter(){
+		OSMWay[] tempWays = incominggraph.getWays();
+		String key;
+		//alle Einträge im Filter durchgehen
+		for (int i = 0; i < filter.length; i++) {
+			//alle Ways durchgehen
+			for (int j = 0; j < tempWays.length; j++) {
+				key = filter[i].getKeyValue();
+				//prüfen, ob Way Key-Wert des Filters enthält
+				if (tempWays[j].hasKey(key)) {
+					//prüfen, ob Way auch einen Value-Wert des Filtereintrags enthält
+					if (filter[i].hasTagValue(tempWays[j].getValue(key))) {
+						//Way outgoinggraph hinzufügen
+						outgoinggraph.addWay(tempWays[j]);
+						for (int j2 = 0; j2 < tempWays[j].getNodes().length; j2++) {
+							//zum way gehörende Nodes einfügen, aber nur, wenn diese
+							//vorher noch nicht im outgoinggraph vorhanden sind
+							if (!outgoinggraph.hasNode(tempWays[j].getNodes()[j2].getId())) {
+								outgoinggraph.addNode(tempWays[j].getNodes()[j2]);
+							}
+							
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public Filter[] getFilter() {
+		return filter;
+	}
+
+	public void setFilter(Filter[] filter) {
+		this.filter = filter;
+	}
+
+	public XMLFilterReader getXmlfilterreader() {
+		return xmlfilterreader;
+	}
+
+	public void setXmlfilterreader(XMLFilterReader xmlfilterreader) {
+		this.xmlfilterreader = xmlfilterreader;
+	}
+
+	public OSMGraph getIncominggraph() {
+		return incominggraph;
+	}
+
+	public void setIncominggraph(OSMGraph incominggraph) {
+		this.incominggraph = incominggraph;
+	}
+
+	public OSMGraph getOutgoinggraph() {
+		return outgoinggraph;
+	}
+
+	public void setOutgoinggraph(OSMGraph outgoinggraph) {
+		this.outgoinggraph = outgoinggraph;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/filter/Filter.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/filter/Filter.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/filter/Filter.java	(revision 25501)
@@ -0,0 +1,45 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.filter;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * @author  joerg
+ */
+public class Filter {
+	
+	private HashSet<String> tagValues = new HashSet<String>();
+	private String keyValue;
+	
+	public Filter(String keyname, ArrayList<String> values) {
+		this.keyValue = keyname;
+		tagValues.addAll(values);
+	}
+	
+	public boolean hasTagValue(String value) {
+		return tagValues.contains(value);
+	}
+	
+	public Filter() {	
+	}
+	
+	public String[] getTagValues() {
+		return (String[])tagValues.toArray();
+	}
+
+	public void setTagValues(HashSet<String> tagValues) {
+		this.tagValues = tagValues;
+	}
+	
+	public void setTagValue(String value) {
+		tagValues.add(value);
+	}
+
+	public String getKeyValue() {
+		return keyValue;
+	}
+
+	public void setKeyValue(String keyValue) {
+		this.keyValue = keyValue;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/BackPropagation.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/BackPropagation.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/BackPropagation.java	(revision 25501)
@@ -0,0 +1,46 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+
+
+/**
+ * Klasse für die Backpropagation
+ * @author  joerg
+ */
+public class BackPropagation {
+
+	private Channel y;
+	private Channel z;
+	private final ChannelDiGraph digraph;
+
+	public BackPropagation(ChannelDiGraph digraph) {
+		this.digraph = digraph;
+	}
+
+	/**
+	 * 
+	 * @param y fromNode
+	 * @param z toNode
+	 */
+	public void backPropagation(Channel y, Channel z, Channel zstrich) {
+		this.y = y;
+		this.z = z;
+		for (int i = 0; i < z.getReachableNodes().size(); i++) {
+			y.addReachableNode(z.getReachableNodeAt(i));
+			//z.appendChannelToPath(i, z);
+			y.appendPath(z.getReachableNodeAt(i), z.getPathsAt(z.getReachableNodeAt(i)));
+			y.appendPath(z.getReachableNodeAt(i), y.getPathsAt(z));
+		}
+		for (int i = 0; i < y.getPredChannels().size(); i++) {
+			if (zstrich !=
+				y.getPredChannels().get(i) &&
+				digraph.getLeadsTo(
+						y.getPredChannels().get(i), y).
+						isForwardEdge()
+			) {
+				backPropagation(y.getPredChannels().get(i), y, zstrich);
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/Combination.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/Combination.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/Combination.java	(revision 25501)
@@ -0,0 +1,122 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+public class Combination {
+	
+	private long n = 0;
+	private long k = 0;
+	long[] data = null;
+	
+	public Combination(long n, long k){
+	    if (n < 0 || k < 0)
+			try {
+				throw new Exception("Negative parameter in constructor");
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}  
+	    this.n = n;
+	    this.k = k;
+	    this.data = new long[(int)k];
+	    for (long i = 0; i < k; ++i)
+	      this.data[(int)i] = i;
+	  }
+	
+	public static long Choose(long n, long k)
+	{
+	  if (n < 0 || k < 0)
+		try {
+			throw new Exception("Invalid negative parameter in Choose()");
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} 
+	  if (n < k) return 0;
+	  if (n == k) return 1;
+
+	  long delta, iMax;
+
+	  if (k < n-k) // ex: Choose(100,3)
+	  {
+	    delta = n-k;
+	    iMax = k;
+	  }
+	  else         // ex: Choose(100,97)
+	  {
+	    delta = k;
+	    iMax = n-k;
+	  }
+
+	  long ans = delta + 1;
+
+	  for (long i = 2; i <= iMax; ++i)
+	  {
+	    ans = (ans * (delta + i)) / i; 
+	  }
+
+	  return ans;
+	}
+	public long Choose()
+	{
+	 
+	  if (n < k) return 0;
+	  if (n == k) return 1;
+
+	  long delta, iMax;
+
+	  if (k < n-k) // ex: Choose(100,3)
+	  {
+	    delta = n-k;
+	    iMax = k;
+	  }
+	  else         // ex: Choose(100,97)
+	  {
+	    delta = k;
+	    iMax = n-k;
+	  }
+
+	  long ans = delta + 1;
+
+	  for (long i = 2; i <= iMax; ++i)
+	  {
+	    ans = (ans * (delta + i)) / i; 
+	  }
+
+	  return ans;
+	}
+
+	
+	public Combination Successor()
+	{
+	  if (this.data.length == 0 ||
+	      this.data[0] == this.n - this.k)
+	    return null;
+
+	  Combination ans = new Combination(this.n, this.k);
+
+	  long i;
+	  for (i = 0; i < this.k; ++i){
+	    ans.data[(int)i] = this.data[(int)i];
+	  }
+	  for (i = this.k - 1; i > 0 && ans.data[(int)i] == this.n - this.k + i; --i) {};
+	 
+	  ++ans.data[(int)i];
+
+	  for (long j = i; j < this.k - 1; ++j){
+	    ans.data[(int)j+1] = ans.data[(int)j] + 1;
+	  }  
+	  return ans;
+	}
+	
+	public String ToString()
+	  {
+	    StringBuilder sb = new StringBuilder();
+	    sb.append("{");
+	    for (long i = 0; i < this.k; ++i){
+	      sb.append(this.data[(int)i]);
+	      if (i<this.k-1) sb.append(", ");
+	    }
+	    sb.append("}");
+	    return sb.toString();
+	  }
+
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JCheck.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JCheck.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JCheck.java	(revision 25501)
@@ -0,0 +1,78 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+
+/**
+ * @author  joerg
+ */
+public class JCheck {
+
+	private int exnr;
+	private String result = "";
+
+	public boolean jCheck(ArrayList<Channel> entries, ArrayList<Channel> exits,
+			int n) {
+		for (int i = 0; i < exits.size(); i++) {
+			exits.get(i).setEnnrZero();
+		}
+		if (!(entries.size() == exits.size() && exits.size() == n)) {
+			result="Rule 1 broken: " + entries.size() + " entries but "
+					+ exits.size() + " exits and n=" + n;
+			return false;
+		}
+		for (int i = 0; i < entries.size(); i++) {
+			if (!(entries.get(i).getIndegree() + entries.get(i).getOutdegree() >= 2)) {
+				result="rule 4 broken: indegree from entrynode with ID: "
+						+ entries.get(i).getNewid() + ": "
+						+ entries.get(i).getIndegree() + " OutDegree: "
+						+ entries.get(i).getOutdegree();
+				return false;
+			}
+			exnr = 0;
+			for (int j = 0; j < exits.size(); j++) {
+				if (!(exits.get(j).getIndegree() + exits.get(j).getOutdegree() >= 2)) {
+					result="Rule 4 broken, indegree from exitnode with ID: "
+							+ exits.get(j).getNewid() + ": "
+							+ exits.get(j).getIndegree() + " and outdegree: "
+							+ exits.get(j).getOutdegree();
+					//log.debug(exits.get(j).toString());
+					return false;
+				}
+				if (entries.get(i).getReachableNodes().contains(exits.get(j))) {
+					exnr++;
+					exits.get(j).increaseEnnr();
+				}
+				if (exits.get(j).equals(entries.get(i))) {
+					result="Rule 2 broken: node with ID: "
+							+ "entries.get(i).getNode().getId()"
+							+ "is both entry and exit node";
+					return false;
+				}
+			}
+
+		}
+		if (!(exnr >= n - 1)) {
+			result="Rule 1 broken";
+			return false;
+		}
+		for (int i = 0; i < exits.size(); i++) {
+			if (!(exits.get(i).getEnnr() >= (n - 1))) {
+				result="Rule 1 broken, exit node with ID "
+						+ exits.get(i).getNewid() + "can only reached from "
+						+ exits.get(i).getEnnr() + " entries.";
+				return false;
+			}
+		}
+		result = "Jcheck erfolgreich bestanden";
+		return true;
+	}
+	
+	/**
+	 * gibt das Ergebnis des JChecks in Form als Satz mit Informationen zurück
+	 * @return
+	 */
+	public String getResult() {
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JMinimality.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JMinimality.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JMinimality.java	(revision 25501)
@@ -0,0 +1,282 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+
+
+
+/**
+ * Testet, dass ein subgraph keine kleinere Junction enth�lt
+ * @author  Jörg Possin, Simon Scheider
+ */
+public class JMinimality {
+
+	private boolean CheckMinimal = true;
+	private final ArrayList<Channel> E;
+	private final int Grid[][];
+	private final ArrayList<Channel> OrEn;
+	private final ArrayList<Channel> OrEx;
+	private final int n;
+	private final List<List<Object>> L = new ArrayList<List<Object>>(); //The list of columns to be sorted
+	private long EEovern = 0;
+	private final HashSet<Channel> subgraph = new HashSet<Channel>();//The candidate subgraph to be tested
+	private double durchlauf = 1;
+	private ProgressMonitor pm;
+	private final boolean pmenabled;
+	private final ArrayList<Integer> anzahlchannels = new ArrayList<Integer>();
+	private final ArrayList<HashSet<Channel>> junctions = new ArrayList<HashSet<Channel>>();
+	private final boolean searchFirstJunction;
+	private final ArrayList<Channel> subJunction = new ArrayList<Channel>();
+	private final JPrepare jprepare;
+	private boolean Check = false;
+	private Iterator<int[]> it;
+
+
+	public JMinimality(int[][] Grid, int n,
+			ArrayList<Channel> E,
+			ArrayList<Channel> entries,
+			ArrayList<Channel> exits,
+			ChannelDiGraph channeldigraph,
+			boolean junctionsearch) {
+
+		this.E = E;
+		this.n = n;
+		this.Grid = Grid;
+		this.OrEn = entries;
+		this.OrEx = exits;
+		this.pmenabled = false;
+		this.searchFirstJunction = junctionsearch;
+		this.jprepare = new JPrepare(channeldigraph);
+	}
+
+	public JMinimality(int[][] Grid, int n,
+			ArrayList<Channel> E,
+			ArrayList<Channel> entries,
+			ArrayList<Channel> exits,
+			ChannelDiGraph channeldigraph,
+			ProgressMonitor pm,
+			boolean junctionsearch) {
+
+		this.E = E;
+		this.n = n;
+		this.Grid = Grid;
+		this.OrEn = entries;
+		this.OrEx = exits;
+		this.pm = pm;
+		this.pmenabled = true;
+		this.searchFirstJunction = junctionsearch;
+		this.jprepare = new JPrepare(channeldigraph);
+		//this.jCheck= new JCheck();
+	}
+
+	public void GenerateSubcolumns () {/*Generates all combinations of subcolumns in the grid*/
+		if (pmenabled) {
+			pm.setCustomText(tr ("generate all combinations from entrie/exit candidates"));
+		}
+
+		Combination c = new Combination(Grid.length, n);
+		EEovern = (int) c.Choose(Grid.length*Grid.length, n*n);
+		long ans = c.Choose(); //This is the number of subcolumns to be generated
+		int[][] v; // this is a column variable containing n y-index entries plus true false values (0/1)
+		List<Object> C; //The column is packed together with 2 indices into this variable
+		for (int i = 0; i < Grid.length;i++) {
+			int h = 0;	//this is the index denoting the "n out of Grid.length"- combination, indicating a subcolumn of length n
+			do {
+				int missing = 0;
+				C = new ArrayList<Object>(3);
+				v = new int[n][2];
+				C.add(i);//the first position of column variable C is the column index
+				C.add(h);//the second is the entry-subset index
+				for(int t = 0; t < c.data.length; t++){
+					if (Grid[(int)c.data[t]][i] == 0){
+						missing++;
+						v[t][1]= 0; //false
+					}
+					else{
+						v[t][1]= 1;
+					} //true
+					v[t][0]=(int)c.data[t];	//Write a y index of the combination into column
+				}
+				if (missing <=1){//If column has at most one missing entry
+					C.add(v);//insert column as the third position of column variable C
+					L.add(C); //Insert C in list to be ordered
+				}
+				h++; //Iterate through all subcolumns
+				if (h < ans){c = c.Successor();}//generate the next combination
+			}while(h < ans);
+			c = new Combination(Grid.length, n); //For each original column in the grid, generate new subcolumns
+		}
+		Collections.sort(L, new Comparator<List<Object>>() {
+			public int compare(List<Object> o1, List<Object> o2) {
+				return (Integer)o1.get(1) - (Integer)o2.get(1); //sort according to h index in each column
+			}});
+	}
+
+	public boolean IterateThroughKn() {//Iterates through all K_{n-1} subgrids of the Grid and tests them
+		if (L.size()==0) {
+			return true;
+		}
+		if (pmenabled) {
+			pm.setTicksCount(L.size());
+			pm.setCustomText("Iterates through all K_{n-1} subgrids of the Grid and tests them");
+		}
+		Combination c;
+		Iterator<List<Object>> l = L.listIterator();
+		List<Object> C;
+		ArrayList<int[]> CandidateK = new ArrayList<int[]>(n*n); //saves the candidate K_{n-1} in entry-exit pairs
+		long lindex= 0;
+		int countk = 0;
+		int h = 0;
+		int m = 0;
+		int[][] v;
+		int x_i;
+		int y_j;
+		int progressmonitorcounter = 1;
+		boolean mchanged = false;
+		boolean hchanged = false;
+		C = l.next();
+		do{ //Loop over list of columns L
+			if (mchanged){
+				C = l.next(); //Iterator in L
+				lindex++; //Index in L
+				if (hchanged) {
+					m=1;
+					hchanged = false;
+				}
+			}
+			if ((Integer)C.get(1)==h && l.hasNext()){ //m counts the set of columns with index h
+				m++;
+				mchanged = true;
+			}
+			else{
+				if (l.hasNext()==false){
+					m++;lindex++;
+				} //At the end of L, counter are set one up
+				c = new Combination(m, n);
+				long ans = c.Choose();
+				int missing = 0;
+				boolean smallerjunction = false;
+				for (int k =0; k<ans;k++){ //Makes sure that subset of m columns contains an n*n subgrid, because ans = m over n would be 0 otherwise
+					for (int y = 0; y < n; y++){//Iterates over all rows of subgrid k
+						missing =0;	//test = "";
+						for (int x = 0; x <c.data.length;x++) { //Iterates over all columns of subgrid k
+							x_i=((Integer)L.get((int)(lindex-m+c.data[x])).get(0));//columnindex in grid
+							v=((int[][])(L.get((int)(lindex-m+c.data[x])).get(2))); //subcolumn of grid
+							y_j= v[y][0]; //rowindex in grid
+							if (v[y][1]==0){
+								missing++;
+							}else{
+								CandidateK.add(new int[]{y_j,x_i});
+							}//save entry/exit tuple
+							if (smallerjunction == false && ((!OrEn.contains(E.get(v[y][0]))) &&(!OrEx.contains(E.get(x_i))))){ // Tests, whether y or x is not an original entry/exit
+								smallerjunction = true; //Then k identifies a different junction than the original one
+							}
+							//test = test+" ("+y_j+", "+x_i+", "+v[y][1]+")";
+						}
+						if (missing > 1){
+							break;
+						}//If a row has more than one missing value, break
+					}
+					if (missing <=1 && smallerjunction == true){//The k-subgrid is a different junction candidate satisfying total reachability
+						countk++;
+						CheckMinimal = CheckSmallJunction(CandidateK)==false;// If the candidate is a smaller junction, then minimality is false
+						durchlauf++;
+						//log.info("durchlauf: " + durchlauf + " Wert von CheckMinimal: " + CheckMinimal);
+						if (!CheckMinimal) {
+							break;
+						}
+					}
+					CandidateK.clear();
+					if (k+1 < ans){c = c.Successor();} //Produces the m over n combinations
+				}
+				m=1; //Sets m to the first column with next index h+1
+				h++;
+				mchanged = false;
+				hchanged = true;
+			}
+			if (pmenabled) {
+				progressmonitorcounter++;
+				pm.setTicks(progressmonitorcounter);
+			}
+		}
+		while(l.hasNext() && CheckMinimal);
+		return CheckMinimal;
+	}
+
+	/**
+	 * gibt true zurück, wenn Kandidat eine Kreuzung ist, aber nicht, wenn junctionsearch auf true gesetzt ist
+	 * @param CandidateK
+	 * @return
+	 */
+	public boolean CheckSmallJunction(ArrayList<int[]> CandidateK){
+		Check = false;
+		subgraph.clear();//Zu konstruierender Subgraph
+		it = CandidateK.iterator();
+		//Reconstruct small Junction from paths
+		while (it.hasNext()){
+			int[]point = it.next();
+			for (int j = 0; j < E.get(point[0]).getReachableNodes().size(); j++) {
+				if(E.get(point[0]).getReachableNodeAt(j).equals(E.get(point[1]))){
+					subgraph.addAll(E.get(point[0]).getPathsAt(E.get(point[0]).getReachableNodeAt(j)));
+					subgraph.add(E.get(point[0]));
+				}
+			}
+		}
+		jprepare.jPrepare(new ArrayList<Channel>(subgraph));
+		JCheck jCheck = new JCheck();
+		Check = jCheck.jCheck(jprepare.getEntries(), jprepare.getExits(), n);
+		jprepare.resetSubgraph();
+		if (Check) {
+			subJunction.clear();
+			subJunction.addAll(subgraph);
+			//soll mehr als ein Kandidat gesucht werden? Dann Kandidaten speichern und Check wieder auf false stellen, damit die Hauptschleife weitergeht
+			if (!searchFirstJunction) {
+				boolean isin = false;
+				for (int i = 0; i < junctions.size(); i++) {
+					//log.debug("Kreuzung " + i +" hat Channels: " + junctions.get(i).size() + " subgraph: " + subgraph.size());
+					if (junctions.get(i).size() == subgraph.size()) {
+						Iterator<Channel> it = subgraph.iterator();
+						isin = true;
+						while (it.hasNext()) {
+							if (!junctions.get(i).contains(it.next())) {
+								isin = false;
+								//log.info("nicht drin");
+							}
+						}
+					}
+				}
+				if (isin == false) {
+					junctions.add(new HashSet<Channel>(subgraph));
+					//log.info("Kreuzungskandidat der Liste zugefügt" + junctions.size());
+				}
+				Check = false;
+			}
+		}
+		return Check;
+	}
+
+	/**
+	 * enthält alle Channels des zuletzt durchlaufenden Kreuzungskandidaten (muß keine gültige Kreuzung sein)
+	 * @return
+	 */
+	public ArrayList<Channel> getSubJunctionCandidate(){
+		return new ArrayList<Channel>(subgraph);
+	}
+
+	/**
+	 * gibt alle gefundenen Kreuzungskandidaten zurück (ist leer, wenn junctionsearch auf true gesetzt wurde)
+	 * @return
+	 */
+	public ArrayList<HashSet<Channel>> getJunctionCandidates() {
+		return junctions;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JPrepare.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JPrepare.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JPrepare.java	(revision 25501)
@@ -0,0 +1,85 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+
+/**
+ * identifiziert die Ein/Ausgänge des übergebenden Teilgraphen. JPrepare setzt die Knotengrade von Vorgänger/nachfolgerknoten der übergebenden Knoten
+ * @author  joerg
+ */
+public class JPrepare {
+
+	private final ArrayList<Channel> entries;
+	private final ArrayList<Channel> exits;
+	private ArrayList<Channel> vertices;
+	private final ChannelDiGraph digraph;
+
+	public JPrepare(ChannelDiGraph digraph) {
+		entries = new ArrayList<Channel>();
+		exits = new ArrayList<Channel>();
+		this.digraph = digraph;
+	}
+
+	public void jPrepare (ArrayList<Channel> vertices) {
+		this.vertices = vertices;
+		entries.clear();
+		exits.clear();
+
+		/*TODO: kann weg?
+		digraph.ereaseChannelsInDegree();
+		digraph.ereaseChannelsOutDegree();
+		digraph.ereaseChannelsSubgraph();
+		 */
+		for (int i = 0; i < vertices.size(); i++) {
+			vertices.get(i).setSubgraph(true);
+		}
+		for (int i = 0; i < vertices.size(); i++) {
+			for (int j = 0; j < vertices.get(i).getPredChannels().size(); j++) {
+				if (vertices.get(i).getPredChannels().get(j).isSubgraph() == false ) {
+					if (!entries.contains(vertices.get(i))) {
+						entries.add(vertices.get(i));
+					}
+				}
+				else {
+					vertices.get(i).countupIndegree();
+					//log.trace(vertices.get(i).toString());
+				}
+			}
+			for (int j = 0; j < vertices.get(i).getLeadsTo().size(); j++) {
+				if (vertices.get(i).getLeadsTo().get(j).getToChannel().isSubgraph() == false) {
+					if (!exits.contains(vertices.get(i))) {
+						exits.add(vertices.get(i));
+					}
+				}
+				else {
+					vertices.get(i).countupOutdegree();
+				}
+			}
+		}
+	}
+
+	public void resetSubgraph(){
+		for (int i = 0; i < vertices.size(); i++) {
+			vertices.get(i).setSubgraph(false);
+			vertices.get(i).setIndegree(0);
+			vertices.get(i).setOutdegree(0);
+		}
+	}
+
+	/**
+	 * gibt die Anzahl der gefundenen Eingänge zurück
+	 * @return
+	 */
+	public ArrayList<Channel> getEntries() {
+		return entries;
+	}
+
+	/**
+	 * gibt die Anzahl der gefundenen Ausgänge zurück
+	 * @return
+	 */
+	public ArrayList<Channel> getExits() {
+		return exits;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JProcess.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JProcess.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JProcess.java	(revision 25501)
@@ -0,0 +1,60 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.connectedness.BacktrackingColors;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
+
+
+/**
+ * erzeugt
+ * @author  joerg
+ */
+public class JProcess {
+
+	private ArrayList<Channel> vertices;
+	private ChannelDiGraph digraph;
+	private TRDFS trdfs;
+	private BackPropagation backpropagation;
+	private ArrayList<LeadsTo> cycleEdges;
+
+	public JProcess(ArrayList<Channel> subgraph, ChannelDiGraph digraph) {
+		this.digraph = digraph;
+		this.vertices = subgraph;
+		this.trdfs = new TRDFS(vertices, digraph);
+		this.backpropagation = new BackPropagation(digraph);
+	}
+
+	/**
+	 * ruft den TR-DFS und danach den Backpropagation-Algorithmus auf jPrepare
+	 * muß vorher durchgelaufen sein (die Eingänge müssen bekannt sein)
+	 * 
+	 * @param entries
+	 */
+	public void jProcess(ArrayList<Channel> entries) {
+		ArrayList<Channel> nodes = digraph.getChannels();
+		// alle Knoten des Subgraphen auf unbesucht stellen und
+		// die evtl. gespeicherten erreichbaren Knoten löschen
+		for (int i = 0; i < nodes.size(); i++) {
+			nodes.get(i).setVisited(BacktrackingColors.WHITE);
+			nodes.get(i).ereaseReachableNodes();
+		}
+		// alle Kanten auf keine ForwardEdge stellen
+		for (int i = 0; i < digraph.getLeadsTo().size(); i++) {
+			digraph.getLeadsTo().get(i).setForwardEdge(false);
+		}
+		trdfs.ereaseCycleEdges();
+
+		for (int i = 0; i < entries.size(); i++) {
+			if (entries.get(i).getVisited() == BacktrackingColors.WHITE) {
+				trdfs.trdfs(entries.get(i));
+			}
+		}
+		cycleEdges = trdfs.getCycleEdges();
+		for (int j = 0; j < cycleEdges.size(); j++) {
+			backpropagation.backPropagation(cycleEdges.get(j).getFromChannel(),
+					cycleEdges.get(j).getToChannel(), cycleEdges.get(j).getToChannel());
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JunctionChecker.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JunctionChecker.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/JunctionChecker.java	(revision 25501)
@@ -0,0 +1,264 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+
+/**
+ * JunctionChecker startet das Überprüfen eines Subgraphen auf eine existierende
+ * Kreuzung
+ *
+ * @author joerg
+ *
+ */
+public class JunctionChecker {
+
+	private ArrayList<Channel> subgraph;
+	private ArrayList<Channel> entries;
+	private ArrayList<Channel> exits;
+	private ArrayList<Channel> cycleedges;
+	private ArrayList<Channel> subjunction;
+	private int n;
+	private final JPrepare jPrepare;
+	private JProcess jProcess;
+	private final ChannelDiGraph channeldigraph;
+	private final JCheck jCheck;
+	private ArrayList<Channel> E;
+	private int Grid[][];
+	private boolean Check;
+	private boolean smallerJunction;
+	private JMinimality m;
+	// Variable wird beim KreuzungsSuchen benutzt, sonst ist sie leer!
+	private ArrayList<HashSet<Channel>> junctions = new ArrayList<HashSet<Channel>>();
+	//dient zur Zeitmessung
+	private long startIterate = 0;
+	private long stopIterate = 0;
+	private long startGenerate = 0;
+
+	public JunctionChecker(ChannelDiGraph channeldigraph, int n) {
+		this.jPrepare = new JPrepare(channeldigraph);
+		this.channeldigraph = channeldigraph;
+		this.n = n;
+		this.jCheck = new JCheck();
+		this.subjunction = new ArrayList<Channel>();
+		smallerJunction = false;
+	}
+
+	/**
+	 * startet das Überprüfen einer Teilmenge auf die Kreuzungskriterien
+	 * @param subgraph
+	 * @param pm
+	 */
+	public void checkjunctions(ArrayList<Channel> subgraph, ProgressMonitor pm) {
+		jPrepare.jPrepare(subgraph);
+		entries = jPrepare.getEntries();
+		exits = jPrepare.getExits();
+		jProcess = new JProcess(subgraph, channeldigraph);
+		jProcess.jProcess(jPrepare.getEntries());
+		boolean result = jCheck.jCheck(entries, exits, n);
+		//jPrepare.resetSubgraph();
+		if (result == true) {
+			this.collectECandidates(subgraph);
+			this.ConstructGrid();
+			m = new JMinimality(Grid, n, E, entries, exits, channeldigraph, pm,
+					true);
+			m.GenerateSubcolumns();
+			Check = m.IterateThroughKn();
+			if (!Check) {
+				smallerJunction = true;
+			}
+			subjunction = m.getSubJunctionCandidate();
+		} else {
+			Check = false;
+		}
+	}
+
+	/**
+	 * Diese Methode wird aufgerufen, wenn nach Kreuzungen in einer Teilmenge
+	 * gesucht werden soll
+	 *
+	 * @param subgraph
+	 * @param firstjunction soll nur die erste mögliche Kreuzung ausgegeben werden oder alle
+	 */
+	public void junctionSearch(ArrayList<Channel> subgraph, ProgressMonitor pm) {
+		jPrepare.jPrepare(subgraph);
+		entries = jPrepare.getEntries();
+		exits = jPrepare.getExits();
+		jProcess = new JProcess(subgraph, channeldigraph);
+		jProcess.jProcess(jPrepare.getEntries());
+		this.collectECandidates(subgraph);
+		this.ConstructGrid();
+		jPrepare.resetSubgraph();
+		m = new JMinimality(Grid, n, E, new ArrayList<Channel>(), new ArrayList<Channel>(), channeldigraph, pm, false);
+		m.GenerateSubcolumns();
+		Check = m.IterateThroughKn();
+		junctions = checkJunctionCandidates(m.getJunctionCandidates());
+	}
+
+	public void junctionSearch(ArrayList<Channel> subgraph) {
+		jPrepare.jPrepare(subgraph);
+		entries = jPrepare.getEntries();
+		exits = jPrepare.getExits();
+		jProcess = new JProcess(subgraph, channeldigraph);
+		jProcess.jProcess(jPrepare.getEntries());
+		this.collectECandidates(subgraph);
+		this.ConstructGrid();
+		jPrepare.resetSubgraph();
+		m = new JMinimality(Grid, n, E, new ArrayList<Channel>(), new ArrayList<Channel>(), channeldigraph, false);
+		startGenerate = System.currentTimeMillis();
+		m.GenerateSubcolumns();
+		startIterate = System.currentTimeMillis();
+		Check = m.IterateThroughKn();
+		stopIterate = System.currentTimeMillis();
+		junctions = checkJunctionCandidates(m.getJunctionCandidates());
+	}
+
+	/**
+	 * Überprüft die Kreuzunskandidaten, die JMinimality gefunden hat, welche davon eine Kreuzung darstellen (eine Kreuzung
+	 * darf keine weiteren Kreuzungen enthalten)
+	 */
+	private ArrayList<HashSet<Channel>> checkJunctionCandidates(ArrayList<HashSet<Channel>> junctioncandidates){
+		ArrayList<HashSet<Channel>> junctions = (ArrayList<HashSet<Channel>>) junctioncandidates.clone();
+		for (int i = 0; i < junctioncandidates.size(); i++) {
+			for (int j = 0; j < junctioncandidates.size(); j++) {
+				if (junctioncandidates.get(i).containsAll(junctioncandidates.get(j))) {
+					junctions.removeAll(junctioncandidates.get(i));
+				}
+				else {
+				}
+			}
+		}
+		return junctions;
+	}
+
+
+	private void collectECandidates(ArrayList<Channel> subgraph) {
+		E = new ArrayList<Channel>();
+		for (int i = 0; i < subgraph.size(); i++) {
+			if ((subgraph.get(i).getIndegree() + subgraph.get(i).getOutdegree() >= 3)
+					|| entries.contains(subgraph.get(i))
+					|| exits.contains(subgraph.get(i))) {
+				E.add(subgraph.get(i));
+			}
+		}
+	}
+
+	private void ConstructGrid() {
+		Grid = new int[E.size()][E.size()];
+		for (int y = 0; y < E.size(); y++) {
+			for (int x = 0; x < E.size(); x++) {
+				if (x != y && !(entries.contains(E.get(x)))
+						&& !(exits.contains(E.get(y)))
+						&& E.get(y).getReachableNodes().contains(E.get(x))) {
+					Grid[y][x] = 1;
+					//log.trace("Grid-Position auf 1 gesetzT (y/x): " + y + ":"
+					//		+ x + "(Entry/exit):" + E.get(y).getNewid() + ":" +
+					//		E.get(x).getNewid());
+				} else {
+					Grid[y][x] = 0;
+				}
+			}
+		}
+	}
+
+	public long getMeasuredIterateTime() {
+		return (stopIterate - startIterate);
+	}
+
+	public long getMeasuredGenerateTime() {
+		return (startIterate - startGenerate);
+	}
+
+	public ArrayList<Channel> getSubgraph() {
+		return subgraph;
+	}
+
+	public void setSubgraph(ArrayList<Channel> subgraph) {
+		this.subgraph = subgraph;
+	}
+
+	public ArrayList<Channel> getEntries() {
+		return entries;
+	}
+
+	public void setEntries(ArrayList<Channel> entries) {
+		this.entries = entries;
+	}
+
+	public ArrayList<Channel> getExits() {
+		return exits;
+	}
+
+	public void setExits(ArrayList<Channel> exits) {
+		this.exits = exits;
+	}
+
+	public ArrayList<Channel> getCycleedges() {
+		return cycleedges;
+	}
+
+	public void setCycleedges(ArrayList<Channel> cycleedges) {
+		this.cycleedges = cycleedges;
+	}
+
+	public int getN() {
+		return n;
+	}
+
+	public void setN(int n) {
+		this.n = n;
+	}
+
+	/**
+	 * gibt die kleinere, gefundene Kreuzung zurück (wenn es sie gibt)
+	 *
+	 * @return
+	 */
+	public ArrayList<Channel> getSubJunction() {
+		return subjunction;
+	}
+
+	/**
+	 * gibt das Ergebnis des JCheck zurück (bei false keine generelle Aussage
+	 * möglich)
+	 *
+	 * @return false = keine Kreuzung ODER enthält kleinere Kreuzung true =
+	 *         Kreuzung
+	 *
+	 */
+	public boolean getCheck() {
+		return Check;
+	}
+
+	/**
+	 * gibt den Wert des JMinimality zurück (wenn er ausgeführt wurde)
+	 *
+	 * @return true = keine kleinere kreuzung, false = kleinere kreuzung
+	 *         enthalten
+	 */
+	public boolean isSmallerJunction() {
+		return smallerJunction;
+	}
+
+	/**
+	 * das Ergebnis des JCheck als String
+	 *
+	 * @return
+	 */
+	public String getJCheckResult() {
+		return jCheck.getResult();
+	}
+
+	/**
+	 * gitb die bei der Kruezungssuche gefundenen Kreuzungen zurück, sonst
+	 * nichts
+	 *
+	 * @return
+	 */
+	public ArrayList<HashSet<Channel>> getJunctions() {
+		return junctions;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/TRDFS.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/TRDFS.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/junctionchecking/TRDFS.java	(revision 25501)
@@ -0,0 +1,75 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.junctionchecking;
+
+import java.util.ArrayList;
+import org.openstreetmap.josm.plugins.JunctionChecker.connectedness.BacktrackingColors;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.LeadsTo;
+
+
+/**
+ * @author  Jörg Possin
+ */
+public class TRDFS {
+
+	private final ArrayList<Channel> vertices;
+	private Channel startNode;
+	private final ArrayList<LeadsTo> cycleEdges;
+	private final ChannelDiGraph digraph;
+
+	/**
+	 * 
+	 * 
+	 * @param adnodes
+	 */
+	public TRDFS(ArrayList<Channel> adnodes, ChannelDiGraph digraph) {
+		this.vertices = adnodes;
+		this.digraph = digraph;
+		this.cycleEdges = new ArrayList<LeadsTo>();
+	}
+
+
+	public void trdfs(Channel startNode) {
+		Channel succNode;
+		startNode.setVisited(BacktrackingColors.GREY);
+		startNode.addReachableNode(startNode);
+		startNode.appendChannelToPath(startNode, startNode);
+		for (int i = 0; i < startNode.getLeadsTo().size(); i++) {
+			succNode = startNode.getLeadsTo().get(i).getToChannel();
+			if (succNode.isSubgraph()) {
+				if (succNode.getVisited() == BacktrackingColors.WHITE) {
+					digraph.setForwardEdge(startNode, succNode);
+					trdfs(succNode);
+				} else if (succNode.getVisited() == BacktrackingColors.GREY) {
+					cycleEdges.add(digraph.getLeadsTo(startNode,
+							succNode));
+				}
+				for (int j = 0; j < succNode.getReachableNodes().size(); j++) {
+
+					startNode.addReachableNode(succNode.getReachableNodeAt(j));
+					succNode.appendChannelToPath(succNode.getReachableNodeAt(j), succNode.getReachableNodeAt(j));
+					succNode.appendChannelToPath(succNode.getReachableNodeAt(j), succNode);
+					startNode.appendPath(succNode.getReachableNodeAt(j), succNode.getPathsAt(succNode.getReachableNodeAt(j)));
+				}
+			}
+
+		}
+		startNode.setVisited(BacktrackingColors.BLACK);
+	}
+
+	public void ereaseCycleEdges() {
+		cycleEdges.clear();
+	}
+
+	public int getCycleedgesSize() {
+		return cycleEdges.size();
+	}
+
+	public LeadsTo getCycleEdgeAt(int i) {
+		return cycleEdges.get(i);
+	}
+
+	public ArrayList<LeadsTo> getCycleEdges() {
+		return cycleEdges;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/ColorSchemeXMLReader.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/ColorSchemeXMLReader.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/ColorSchemeXMLReader.java	(revision 25501)
@@ -0,0 +1,55 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.reader;
+
+import java.awt.Color;
+import java.util.HashMap;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+
+public class ColorSchemeXMLReader extends XMLReader{
+
+	private HashMap<String, Color> colorScheme;
+
+	public ColorSchemeXMLReader(String filename) {
+		super(filename);
+		parseXML();
+	}
+
+	/**
+	 * gibt die zu dieser Objektklasse gespeicherte Farbe zurück
+	 * @param s Objektklasse
+	 * @return die passende Farbe, existiert keine wird grey zurückgegeben
+	 */
+	public Color getColor(String s) {
+		if (colorScheme.containsKey(s)) {
+			return colorScheme.get(s);
+		}
+		else {
+			return Color.GRAY;
+		}
+	}
+
+	@Override
+	public void parseXML() {
+		colorScheme = new HashMap<String, Color>();
+		String tempValue;
+		//String tempKeyValue ="";
+		try {
+			while (parser.hasNext()) {
+				switch (parser.getEventType()) {
+
+				case XMLStreamConstants.START_ELEMENT:
+					tempValue = parser.getAttributeValue(null, "color");
+					if (tempValue != null) {
+						String[] erg = tempValue.split(",");
+						Color c = new Color(Integer.parseInt(erg[0]), Integer.parseInt(erg[1]), Integer.parseInt(erg[2]));
+						colorScheme.put(parser.getLocalName(),c);
+					}
+					break;
+				}
+				parser.next();
+			}
+		} catch (XMLStreamException e) {
+			System.out.println(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/OSMXMLReader.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/OSMXMLReader.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/OSMXMLReader.java	(revision 25501)
@@ -0,0 +1,187 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.reader;
+
+import java.io.File;
+import java.util.HashMap;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMEntity;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMNode;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMRelation;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMWay;
+
+/**
+ * @author  joerg
+ */
+public class OSMXMLReader extends XMLReader {
+
+	private OSMGraph osmgraph = new OSMGraph();
+
+	public OSMXMLReader(String filename) {
+		super(filename);
+	}
+
+	public OSMXMLReader(File file) {
+		super(file);
+	}
+
+	private void readAttributes(OSMEntity entity) {
+		String temp = parser.getAttributeValue(null, "changeset");
+		if (temp != null) {
+			entity.setChangeset(Integer.parseInt(temp));
+		}
+		entity.setId(Long.parseLong(parser.getAttributeValue(null, "id")));
+		entity.setTimestamp(parser.getAttributeValue(null, "timestamp"));
+
+		temp = parser.getAttributeValue(null, "uid");
+		if (temp != null)
+			entity.setUid(Integer.parseInt(temp));
+
+		temp = parser.getAttributeValue(null, "uid");
+		if (temp != null) {
+			entity.setUid(Integer.parseInt(temp));
+		}
+		entity.setUser(parser.getAttributeValue(null, "user"));
+
+		temp = parser.getAttributeValue(null, "visible");
+		if (temp != null) {
+			if (temp.equals("true") || temp.equals("1")) {
+				entity.setVisible(true);
+			}
+		} else {
+			entity.setVisible(false);
+		}
+		temp = parser.getAttributeValue(null, "version");
+		if (temp != null) {
+			entity.setversion(Integer.parseInt(temp));
+		}
+	}
+
+	private void readMember(OSMRelation relation) {
+		if (parser.getAttributeValue(null, "type").equals("node")) {
+			relation.addMember(osmgraph.getNode(Integer.parseInt(parser
+					.getAttributeValue(null, "ref"))), parser
+					.getAttributeValue(null, "role"));
+		}
+		else if (parser.getAttributeValue(null, "type").equals("way")) {
+			relation.addMember(osmgraph.getWay(Long.parseLong(parser
+					.getAttributeValue(null, "ref"))), parser
+					.getAttributeValue(null, "role"));
+		}
+		else if (parser.getAttributeValue(null, "type").equals("relation")) {
+			relation.addMember(osmgraph.getRelation(Integer.parseInt(parser
+					.getAttributeValue(null, "ref"))), parser
+					.getAttributeValue(null, "role"));
+		}
+	}
+
+	@Override
+	public void parseXML() {
+		String xmlelement;
+		OSMNode node = new OSMNode();
+		OSMWay way = new OSMWay();
+		OSMRelation relation = new OSMRelation();
+		HashMap<String, String> hashmap = new HashMap<String, String>();
+		try {
+			while (parser.hasNext()) {
+				switch (parser.getEventType()) {
+
+				case XMLStreamConstants.START_ELEMENT:
+					xmlelement = parser.getLocalName();
+
+					if (xmlelement.equals("node")) {
+						node = new OSMNode();
+						hashmap = new HashMap<String, String>();
+						readAttributes(node);
+						node.setLatitude(Double.parseDouble(parser
+								.getAttributeValue(null, "lat")));
+						node.setLongitude(Double.parseDouble(parser
+								.getAttributeValue(null, "lon")));
+					}
+
+					if (xmlelement.equals("way")) {
+						way = new OSMWay();
+						hashmap = new HashMap<String, String>();
+						readAttributes(way);
+					}
+
+					if (xmlelement.equals("relation")) {
+						relation = new OSMRelation();
+						hashmap = new HashMap<String, String>();
+						readAttributes(relation);
+					}
+
+					if (xmlelement.equals("member")) {
+						readMember(relation);
+					}
+
+					if (xmlelement.equals("bounds")) {
+						osmgraph.setBbbottom(Double.parseDouble(parser
+								.getAttributeValue(null, "minlat")));
+						osmgraph.setBbtop(Double.parseDouble(parser
+								.getAttributeValue(null, "maxlat")));
+						osmgraph.setBbleft(Double.parseDouble(parser
+								.getAttributeValue(null, "minlon")));
+						osmgraph.setBbright(Double.parseDouble(parser
+								.getAttributeValue(null, "maxlon")));
+					}
+
+					if (xmlelement.equals("nd")) {
+						way.addNode(osmgraph.getNode(Integer.parseInt(parser
+								.getAttributeValue(0))));
+					}
+
+					if (xmlelement.equals("tag")) {
+						hashmap.put(parser.getAttributeValue(null, "k"), parser
+								.getAttributeValue(null, "v"));
+					}
+
+					if (xmlelement.equals("relation")) {
+						relation = new OSMRelation();
+						hashmap = new HashMap<String, String>();
+						readAttributes(relation);
+					}
+
+					//TODO: kann wohl wech!
+					/*
+					if (xmlelement.equals("member")) {
+						relation.addMember(parser.getAttributeValue(null,
+								"type"), Integer.parseInt(parser
+								.getAttributeValue(null, "ref")), parser
+								.getAttributeValue(null, "role"));
+					}
+					 */
+					break;
+
+				case XMLStreamConstants.END_ELEMENT:
+					if (parser.getLocalName() == "node") {
+						node.setHashmap(hashmap);
+						osmgraph.addNode(node);
+					}
+
+					if (parser.getLocalName() == "way") {
+						way.setHashmap(hashmap);
+						osmgraph.addWay(way);
+					}
+
+					if (parser.getLocalName().equals("relation")) {
+						relation.setHashmap(hashmap);
+						osmgraph.addRelation(relation);
+					}
+					break;
+				}
+				parser.next();
+			}
+		} catch (XMLStreamException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public void setOSMGraph(OSMGraph osmgraph) {
+		this.osmgraph = osmgraph;
+	}
+
+	public OSMGraph getOSMGraph() {
+		return osmgraph;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/XMLFilterReader.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/XMLFilterReader.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/XMLFilterReader.java	(revision 25501)
@@ -0,0 +1,59 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.reader;
+
+import java.util.Vector;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import org.openstreetmap.josm.plugins.JunctionChecker.filter.Filter;
+
+/**
+ * @author  joerg
+ */
+public class XMLFilterReader extends XMLReader{
+
+	Vector<Filter> filters;
+	Filter filter;
+
+	public XMLFilterReader(String filename) {
+		super(filename);
+		filters = new Vector<Filter>();
+	}
+
+	@Override
+	public void parseXML() {
+		String tempValue ="";
+		String tempKeyValue ="";
+		try {
+			while (parser.hasNext()) {
+
+				switch (parser.getEventType()) {
+				case XMLStreamConstants.START_ELEMENT:
+					tempValue = parser.getAttributeValue(null, "entity");
+					if (tempValue.equals("k")) {
+						filter = new Filter();
+						filter.setKeyValue(parser.getLocalName());
+						tempKeyValue = parser.getLocalName();
+					}
+					if (tempValue.equalsIgnoreCase("v")) {
+						filter.setTagValue(parser.getLocalName());
+					}
+					break;
+
+				case XMLStreamConstants.END_ELEMENT:
+					if (tempKeyValue.equalsIgnoreCase(parser.getLocalName())) {
+						filters.add(filter);
+					}
+					break;
+
+				}
+				parser.next();
+			}
+		} catch (XMLStreamException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public Filter[] getFilters() {
+		Filter[] filterarray= new Filter[filters.size()];
+		return filters.toArray(filterarray);
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/XMLReader.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/XMLReader.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/reader/XMLReader.java	(revision 25501)
@@ -0,0 +1,37 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.reader;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+public  abstract class XMLReader {
+	
+	protected String filename;
+	protected XMLInputFactory factory = XMLInputFactory.newInstance();
+	protected XMLStreamReader parser;
+	 
+	public XMLReader(String filename) {
+		try {
+			parser = factory
+				.createXMLStreamReader(this.getClass().getResourceAsStream(filename));
+		} catch (XMLStreamException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public XMLReader(File file) {
+		try {
+			parser = factory
+					.createXMLStreamReader(new FileInputStream(file));
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (XMLStreamException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public abstract void parseXML();
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/util/RelationProducer.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/util/RelationProducer.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/util/RelationProducer.java	(revision 25501)
@@ -0,0 +1,65 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.util;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.plugins.JunctionChecker.JunctionCheckerPlugin;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+
+/**
+ * Hilfsklasse zum Umwandeln eines CHannels-Hashsets (welches eine Kreuzung repräsentiert) in eine gültige Relation auf den DigraphLayer Relation wird nur dann erzeugt, wenn sie noch nicht existiert
+ * @author  joerg
+ */
+public class RelationProducer {
+
+	private JunctionCheckerPlugin plugin;
+	private HashSet<HashSet<Channel>> storedRelations;
+
+	public RelationProducer(JunctionCheckerPlugin plugin) {
+		this.plugin = plugin;
+		storedRelations = new HashSet<HashSet<Channel>>();
+	}
+
+	public void produceRelation(HashSet<Channel> subset, int n) {
+		if (isProduced(subset)) {
+			return;
+		}
+		LinkedList<OsmPrimitive> ways = new LinkedList<OsmPrimitive>();
+		Iterator<Channel> cit = subset.iterator();
+		while (cit.hasNext()) {
+			Channel c = cit.next();
+			// System.out.println(c.getWay().getId());
+			if (!(ways.contains(plugin.getOsmlayer().data.getPrimitiveById(c
+					.getWay().getId(), OsmPrimitiveType.WAY)))) {
+				ways.add(plugin.getOsmlayer().data.getPrimitiveById(c.getWay()
+						.getId(), OsmPrimitiveType.WAY));
+			}
+		}
+		Main.map.mapView.setActiveLayer(plugin.getOsmlayer());
+		plugin.getOsmlayer().data.setSelected(ways);
+
+		Relation jrelation = new Relation();
+		jrelation.put("type", "junction");
+		jrelation.put("n", Integer.toString(n));
+		for (int i = 0; i < ways.size(); i++) {
+			jrelation.addMember(new RelationMember("part of", ways.get(i)));
+		}
+
+		plugin.getOsmlayer().data.addPrimitive(jrelation);
+	}
+
+	private boolean isProduced(HashSet<Channel> subset) {
+		if (storedRelations.contains(subset)) {
+			return true;
+		} else {
+			storedRelations.add(subset);
+		}
+		return false;
+	}
+}
Index: /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/writing/OSMXMLWriter.java
===================================================================
--- /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/writing/OSMXMLWriter.java	(revision 25501)
+++ /applications/editors/josm/plugins/junctionchecking/src/org/openstreetmap/josm/plugins/JunctionChecker/writing/OSMXMLWriter.java	(revision 25501)
@@ -0,0 +1,114 @@
+package org.openstreetmap.josm.plugins.JunctionChecker.writing;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.Channel;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.ChannelDiGraph;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMEntity;
+import org.openstreetmap.josm.plugins.JunctionChecker.datastructure.OSMNode;
+
+/**
+ * @author  joerg
+ */
+public class OSMXMLWriter {
+
+	String filename;
+	ChannelDiGraph digraph;
+	XMLStreamWriter writer;
+
+	public OSMXMLWriter(String filename, ChannelDiGraph digraph) {
+		this.filename = filename;
+		this.digraph = digraph;
+	}
+
+	public void writeXML() throws FileNotFoundException, XMLStreamException {
+		XMLOutputFactory factory = XMLOutputFactory.newInstance();
+		writer = factory.createXMLStreamWriter(
+		                                   new FileOutputStream(  filename ) );
+		// Der XML-Header wird erzeugt
+		writer.writeStartDocument("utf-8", "1.0");
+		// Zuerst wird das Wurzelelement mit Attribut geschrieben
+		  writer.writeStartElement( "osm" );
+		    writer.writeAttribute( "version", "0.6" );
+		    writer.writeAttribute("generator", "channelGenerator");
+
+		    writer.writeEmptyElement("bounds");
+		    writer.writeAttribute("minlat", Double.toString(digraph.getBbbottom()));
+		    writer.writeAttribute("minlon", Double.toString(digraph.getBbleft()));
+		    writer.writeAttribute("maxlat", Double.toString(digraph.getBbtop()));
+		    writer.writeAttribute("maxlon", Double.toString(digraph.getBbright()));
+
+
+		    OSMNode[] nodes = digraph.getAllOSMNodes();
+		    for (int i = 0; i < nodes.length; i++) {
+		    	//writer.writeStartElement("node");
+		    	writer.writeEmptyElement("node");
+		    	writeAttributes(nodes[i]);
+			}
+
+		    ArrayList<Channel> ways = digraph.getChannels();
+		    for (int i = 0; i < ways.size(); i++) {
+				writer.writeStartElement("way");
+				writer.writeAttribute("id", Integer.toString(ways.get(i).getNewid()));
+				writeAttributes(ways.get(i).getWay());
+				  writer.writeEmptyElement("nd");
+				  writer.writeAttribute("ref", Long.toString(ways.get(i).getFromNode().getId()));
+				  //writer.writeEndElement();
+				  writer.writeEmptyElement("nd");
+				  writer.writeAttribute("ref", Long.toString(ways.get(i).getToNode().getId()));
+				  //writer.writeEndElement();
+
+				  HashMap<String, String> tags = ways.get(i).getWay().getHashmap();
+				  Set<String> keys = tags.keySet();
+				  String t;
+				  Iterator<String> iterator = keys.iterator();
+				  while (iterator.hasNext()) {
+						t = iterator.next();
+						writer.writeEmptyElement("tag");
+						writer.writeAttribute("k", t);
+						writer.writeAttribute("v", tags.get(t));
+					  }
+				  writer.writeEmptyElement("tag");
+				  writer.writeAttribute("k", "ID");
+				  writer.writeAttribute("v", Integer.toString(ways.get(i).getNewid()));
+				  writer.writeEmptyElement("tag");
+                  writer.writeAttribute("k", "SCC");
+                  if (ways.get(i).isStrongConnected()) {
+                      writer.writeAttribute("v", "true");
+                  }
+                  else {
+                      writer.writeAttribute("v", "false");
+                  }
+                  writer.writeEndElement();
+			}
+
+		  writer.writeEndElement();
+		writer.writeEndDocument();
+		writer.close();
+	}
+
+	private void writeAttributes(OSMEntity ent) throws FileNotFoundException, XMLStreamException{
+		if (ent instanceof OSMNode) {
+			writer.writeAttribute("id", Long.toString(ent.getId()) );
+			writer.writeAttribute("lat", Double.toString(((OSMNode) ent).getLatitude()));
+			writer.writeAttribute("lon", Double.toString(((OSMNode) ent).getLongitude()));
+		}
+
+    	if (ent.getTimestamp()!=null) {
+    		writer.writeAttribute("timestamp", ent.getTimestamp());
+    	}
+    	if (ent.isVisible())
+    		writer.writeAttribute("visible", "true");
+    	else writer.writeAttribute("visible", "false");
+		writer.writeAttribute("version", Integer.toString(ent.getVersion()));
+	}
+}
