Index: photoadjust/.classpath
===================================================================
--- photoadjust/.classpath	(revision 35109)
+++ photoadjust/.classpath	(working copy)
@@ -1,7 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="buildtest" path="test/unit">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
+	<classpathentry kind="lib" path="../00_core_test_lib/jmockit.jar"/>
 	<classpathentry kind="output" path="build"/>
 </classpath>
Index: photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustPlugin.java
===================================================================
--- photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustPlugin.java	(revision 35109)
+++ photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustPlugin.java	(working copy)
@@ -8,6 +8,6 @@
 import java.util.List;
 
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
@@ -36,4 +37,5 @@
     public PhotoAdjustPlugin(PluginInformation info) {
         super(info);
         GeoImageLayer.registerMenuAddition(new UntaggedGeoImageLayerAction());
+        GeoImageLayer.registerMenuAddition(new SetDirectionToASequence());
         PhotoPropertyEditor.init();

         initAdapters();
     }
 
Index: photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/SetDirectionToASequence.java
===================================================================
--- photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/SetDirectionToASequence.java	(nonexistent)
+++ photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/SetDirectionToASequence.java	(working copy)
@@ -0,0 +1,78 @@
+package org.openstreetmap.josm.plugins.photoadjust;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JMenuItem;
+
+import org.openstreetmap.josm.data.ImageData;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
+import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
+import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
+
+public class SetDirectionToASequence extends AbstractAction implements LayerAction {
+
+    public SetDirectionToASequence() {
+        super(tr("Set every image to look at the next one in the sequence"), null);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+        GeoImageLayer layer = getSelectedLayer();
+
+        List<ImageEntry> images = layer.getImageData().getImages();
+        normalizeSequence(images, layer.getImageData());
+    }
+
+    public void normalizeSequence(List<ImageEntry> images, ImageData data) {
+    	Double lastDirection = null;
+    	for (int i = 0; i < images.size(); i++) {
+    		ImageEntry entry = images.get(i);
+    		if (i + 1 < images.size()) {
+    			lastDirection = changeDirection(entry, images.get(i + 1), data);
+    		}
+    		if (lastDirection != null) {
+    			data.updateImageDirection(entry, lastDirection);
+    		}
+    	}
+    }
+    
+    private static GeoImageLayer getSelectedLayer() {
+        return (GeoImageLayer)LayerListDialog.getInstance().getModel()
+                .getSelectedLayers().get(0);
+    }
+
+    private Double changeDirection(ImageEntry photo, ImageEntry next, ImageData data) {
+        final LatLon photoLL = photo.getPos();
+        if (photoLL == null) {
+            // Direction cannot be set if image doesn't have a position.
+            return null;
+        }
+        final LatLon mouseLL = next.getPos();
+        // The projection doesn't matter here.
+        double direction = photoLL.bearing(mouseLL) * 360.0 / 2.0 / Math.PI;
+        if (direction < 0.0) {
+            direction += 360.0;
+        } else if (direction >= 360.0) {
+            direction -= 360.0;
+        }
+        return direction;
+    }
+
+    @Override
+    public boolean supportLayers(List<Layer> layers) {
+        return layers.size() == 1 && layers.get(0) instanceof GeoImageLayer;
+    }
+
+    @Override
+    public Component createMenuComponent() {
+        return new JMenuItem(this);
+    }
+}
Index: photoadjust/test/unit/org/openstreetmap/josm/plugins/photoadjust/SetDirectionToASequenceTest.java
===================================================================
--- photoadjust/test/unit/org/openstreetmap/josm/plugins/photoadjust/SetDirectionToASequenceTest.java	(nonexistent)
+++ photoadjust/test/unit/org/openstreetmap/josm/plugins/photoadjust/SetDirectionToASequenceTest.java	(working copy)
@@ -0,0 +1,71 @@
+package org.openstreetmap.josm.plugins.photoadjust;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import org.junit.Test;
+import org.openstreetmap.josm.data.ImageData;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
+import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
+
+import mockit.Delegate;
+import mockit.Expectations;
+import mockit.Mocked;
+
+public class SetDirectionToASequenceTest {
+
+	@Test
+	public void testChangeDirectionToASequence() {
+		SetDirectionToASequence setdirection = new SetDirectionToASequence();
+		
+		ArrayList<ImageEntry> list = new ArrayList<>();
+        ImageEntry first = new ImageEntry(new File("test1"));
+        ImageEntry last = new ImageEntry(new File("test3"));
+        ImageEntry middle = new ImageEntry(new File("test2"));
+        list.add(first);
+        list.add(middle);
+        list.add(last);
+        
+        ImageData data = new ImageData(list);
+        
+        new Expectations(first) {{
+            first.getPos(); result = new CachedLatLon(0, 0);
+        }};
+        
+        new Expectations(middle) {{
+            middle.getPos(); result = new CachedLatLon(0, 1);
+        }};
+        
+        new Expectations(last) {{
+            last.getPos(); result = new CachedLatLon(0, 0);
+        }};
+        
+        new Expectations(data) {{
+            data.updateImageDirection(first, 90);
+            data.updateImageDirection(middle, 270);
+            data.updateImageDirection(last, 270);
+        }};
+        
+		setdirection.normalizeSequence(list, data);
+	}
+	
+	@Test
+	public void testChangeDirectionWithNullPosition() {
+		SetDirectionToASequence setdirection = new SetDirectionToASequence();
+		
+		ArrayList<ImageEntry> list = new ArrayList<>();
+        ImageEntry first = new ImageEntry(new File("test1"));
+        ImageEntry last = new ImageEntry(new File("test3"));
+        list.add(first);
+        list.add(last);
+        
+        ImageData data = new ImageData(list);
+        
+        new Expectations(first) {{
+            first.getPos(); result = null;
+        }};
+        
+		setdirection.normalizeSequence(list, data);
+	}
+
+}
