diff --git a/appointment-import/src/main/java/smash/appointment/parse/AppointmentDao.java b/appointment-import/src/main/java/smash/appointment/parse/AppointmentDao.java
index 4f129832054eefadc935163d11100d35cbf9e3e5..d523a6f821616d59482b532bb14202b5289d8eb1 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/AppointmentDao.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/AppointmentDao.java
@@ -1,13 +1,22 @@
 package smash.appointment.parse;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
 
 public class AppointmentDao {
-	private List<AppointmentEntry> appointments = new ArrayList<>();
+	Logger												 logger				= Logger.getLogger(AppointmentDao.class);
+	private List<AppointmentEntry> appointments	= new ArrayList<>();
 
 	public void addAppointments(List<AppointmentEntry> appointmentsToAdd) {
-		appointments.addAll(appointmentsToAdd);
+		for (AppointmentEntry appointmentEntry : appointmentsToAdd) {
+			addAppointment(appointmentEntry);
+		}
 	}
 
 	/**
@@ -19,11 +28,79 @@ public class AppointmentDao {
 	}
 
 	/**
-	 * @param appointments the appointments to set
+	 * @param appointments
+	 *          the appointments to set
 	 * @see #appointments
 	 */
 	public void setAppointments(List<AppointmentEntry> appointments) {
 		this.appointments = appointments;
 	}
 
+	public List<Visit> getVisits() {
+		List<Visit> result = new ArrayList<>();
+		Map<Subject, List<AppointmentEntry>> subjectAppointments = new HashMap<>();
+		for (AppointmentEntry entry : appointments) {
+			if (subjectAppointments.get(entry.getSubject()) == null) {
+				subjectAppointments.put(entry.getSubject(), new ArrayList<AppointmentEntry>());
+			}
+			subjectAppointments.get(entry.getSubject()).add(entry);
+		}
+		for (Subject subject : subjectAppointments.keySet()) {
+			result.addAll(getVisitsForSubject(subject, subjectAppointments.get(subject)));
+		}
+		return result;
+	}
+
+	private List<Visit> getVisitsForSubject(Subject subject, List<AppointmentEntry> list) {
+		Comparator<AppointmentEntry> comparator = new Comparator<AppointmentEntry>() {
+
+			@Override
+			public int compare(AppointmentEntry o1, AppointmentEntry o2) {
+				String date1 = o1.getDay().substring(0, 10);
+				String date2 = o2.getDay().substring(0, 10);
+				if (date1.compareTo(date2) == 0) {
+					if (o1.getTypes().contains(AppointmentType.LEVEL_A) || o1.getTypes().contains(AppointmentType.LEVEL_A_TQ)) {
+						return -1;
+					} else if (o2.getTypes().contains(AppointmentType.LEVEL_A) || o2.getTypes().contains(AppointmentType.LEVEL_A_TQ)) {
+						return 1;
+					} else {
+						return 0;
+					}
+				} else {
+					return date1.compareTo(date2);
+				}
+			}
+		};
+		Collections.sort(list, comparator);
+
+		List<Visit> result = new ArrayList<>();
+		Visit currentVisit = new Visit(subject);
+		for (AppointmentEntry appointmentEntry : list) {
+			if (appointmentEntry.getTypes().contains(AppointmentType.LEVEL_A) || appointmentEntry.getTypes().contains(AppointmentType.LEVEL_A_TQ)) {
+				if (currentVisit.getAppointments().size() > 0) {
+					result.add(currentVisit);
+				}
+
+				currentVisit = new Visit(subject);
+				currentVisit.addAppointment(appointmentEntry);
+			} else {
+				String date = currentVisit.getLastAppointmentDate();
+				if (date.equals(appointmentEntry.getDay().substring(0, 10))) {
+					currentVisit.getLastAppointment().addTypes(appointmentEntry.getTypes());
+				} else {
+					currentVisit.addAppointment(appointmentEntry);
+				}
+			}
+		}
+		if (currentVisit.getAppointments().size() > 0) {
+			result.add(currentVisit);
+		}
+		return result;
+	}
+
+	public void addAppointment(AppointmentEntry appointment) {
+		appointments.add(appointment);
+
+	}
+
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java b/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java
index b6e872864e644b741c49827eebf3714a463e8a47..d001600fb6f5aaf84825a0d08a562c4a630a4338 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/AppointmentEntry.java
@@ -1,6 +1,7 @@
 package smash.appointment.parse;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 public class AppointmentEntry {
@@ -124,4 +125,10 @@ public class AppointmentEntry {
 		}
 
 	}
+	public void addTypes(Collection<AppointmentType> typesToAdd) {
+		for (AppointmentType appointmentType : typesToAdd) {
+			addType(appointmentType);
+		}
+
+	}
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/Main.java b/appointment-import/src/main/java/smash/appointment/parse/Main.java
index ab43800c01a62fdc10ed64dc7a307bbd98eaadfb..fc5c27b2325be9fb0b52f472ff0d7756d2b1a619 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/Main.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/Main.java
@@ -1,6 +1,10 @@
 package smash.appointment.parse;
 
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
@@ -26,12 +30,14 @@ public class Main {
 		Option flyingTeam = Option.builder().required().argName("file").hasArg().desc("PRC flying-team").longOpt("flying-team").build();
 		Option lihControls = Option.builder().required().argName("file").hasArg().desc("LIH controls").longOpt("lih-controls").build();
 		Option lihMappingControls = Option.builder().required().argName("file").hasArg().desc("LIH controls mapping").longOpt("lih-mapping").build();
+		Option redCap = Option.builder().required().argName("file").hasArg().desc("RedCap appointments").longOpt("red-cap").build();
 		options.addOption(agenda);
 		options.addOption(subjects);
 		options.addOption(controls);
 		options.addOption(flyingTeam);
 		options.addOption(lihControls);
 		options.addOption(lihMappingControls);
+		options.addOption(redCap);
 
 		CommandLineParser parser = new DefaultParser();
 		try {
@@ -65,7 +71,9 @@ public class Main {
 			}
 
 			String agendaFile = line.getOptionValue("agenda");
-			appointmentDao.addAppointments(processPrcAppointments(agendaFile));
+			Calendar today = Calendar.getInstance();
+			today.set(Calendar.HOUR, 5);
+			appointmentDao.addAppointments(processPrcAppointments(agendaFile, today));
 
 			SubjectSqlExporter subjectSqlExporter = new SubjectSqlExporter();
 			// logger.debug("SUBJECTS: ");
@@ -105,10 +113,10 @@ public class Main {
 		return parser.processExcel(controlsFile);
 	}
 
-	private List<AppointmentEntry> processPrcAppointments(String agendaFile) throws Exception {
+	private List<AppointmentEntry> processPrcAppointments(String agendaFile, Calendar minDate) throws Exception {
 		XlsxCalendarProcessor processor = new XlsxCalendarProcessor();
 		processor.setSubjectDao(subjectDao);
-		List<AppointmentEntry> entries = processor.processExcel(agendaFile);
+		List<AppointmentEntry> entries = processor.processExcel(agendaFile, minDate);
 
 		return entries;
 	}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/Visit.java b/appointment-import/src/main/java/smash/appointment/parse/Visit.java
new file mode 100644
index 0000000000000000000000000000000000000000..68b0538c7648dc4468f57160f8c4b5e5dadadccc
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/Visit.java
@@ -0,0 +1,87 @@
+package smash.appointment.parse;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+public class Visit {
+
+	private Subject												 subject;
+	private List<AppointmentEntry> appointments	= new ArrayList<>();
+
+	public Visit(Subject subject) {
+		this.subject = subject;
+	}
+
+	public void addAppointment(AppointmentEntry entry) {
+		appointments.add(entry);
+	}
+
+	/**
+	 * @return the appointments
+	 * @see #appointments
+	 */
+	public List<AppointmentEntry> getAppointments() {
+		return appointments;
+	}
+
+	/**
+	 * @param appointments
+	 *          the appointments to set
+	 * @see #appointments
+	 */
+	public void setAppointments(List<AppointmentEntry> appointments) {
+		this.appointments = appointments;
+	}
+
+	public String getLastAppointmentDate() {
+		if (appointments.size() == 0) {
+			return "1900-01-01";
+		}
+		return getLastAppointment().getDay().substring(0, 10);
+	}
+
+	public AppointmentEntry getLastAppointment() {
+		if (appointments.size() > 0) {
+			return appointments.get(appointments.size() - 1);
+		} else {
+			return null;
+		}
+	}
+
+	public String getStartDate() {
+		if (appointments.size() > 0) {
+			return appointments.get(0).getDay().substring(0, 10);
+		} else {
+			return "1900-01-01";
+		}
+	}
+
+	private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
+
+	public String getEndDate() throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(DATE_FORMATTER.parse(getStartDate()));
+		calendar.add(Calendar.MONTH, 3);
+		return DATE_FORMATTER.format(calendar.getTime());
+	}
+
+	/**
+	 * @return the subject
+	 * @see #subject
+	 */
+	public Subject getSubject() {
+		return subject;
+	}
+
+	/**
+	 * @param subject the subject to set
+	 * @see #subject
+	 */
+	public void setSubject(Subject subject) {
+		this.subject = subject;
+	}
+
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java b/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..65d38b02065118062a468e9ee44db57ac864061e
--- /dev/null
+++ b/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java
@@ -0,0 +1,36 @@
+package smash.appointment.parse;
+
+import java.text.ParseException;
+
+public class VisitSqlExporter {
+
+	public String toSql(Visit visit, boolean isFinished) throws ParseException {
+		StringBuilder result = new StringBuilder("");
+
+		result.append("insert into web_visit (");
+		result.append("subject_id,	 ");
+		result.append("datetime_begin, ");
+		result.append("datetime_end, ");
+		result.append("is_finsished)");
+		result.append("date_born) ");
+
+		result.append("values (");
+		result.append("SELECT id from web_subject where screening_number = "+getStringVal(visit.getSubject().getScreeningNumber()) + ",");
+		result.append(getStringVal(visit.getStartDate()) + ",");
+		result.append(getStringVal(visit.getEndDate()) + ",");
+		result.append(isFinished);
+		result.append(");");
+
+		return result.toString();
+	}
+
+	private String getStringVal(String arg) {
+		if (arg == null) {
+			return "null";
+		} else if (arg.isEmpty()) {
+			return "''";
+		} else {
+			return "'" + arg + "'";
+		}
+	}
+}
diff --git a/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java b/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java
index 7dfe846da8989090855d2bdc58e1fb041f73121c..0c6e2a1419f1cbfc83e1eaafebedafed8553ca88 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/XlsxCalendarProcessor.java
@@ -1,22 +1,21 @@
 package smash.appointment.parse;
 
 import java.io.FileInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
-import org.apache.poi.EncryptedDocumentException;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
@@ -30,7 +29,7 @@ public class XlsxCalendarProcessor {
 
 	private SubjectDao subjectDao;
 
-	public List<AppointmentEntry> processExcel(String filename) throws EncryptedDocumentException, InvalidFormatException, IOException, ParseException {
+	public List<AppointmentEntry> processExcel(String filename, Calendar minDate) throws Exception {
 		List<AppointmentEntry> result = new ArrayList<AppointmentEntry>();
 		InputStream inp = new FileInputStream(filename);
 		Workbook workbook = WorkbookFactory.create(inp);
@@ -46,9 +45,32 @@ public class XlsxCalendarProcessor {
 				logger.debug("Skipping sheet: " + name);
 			}
 		}
+		if (minDate != null) {
+			Set<AppointmentEntry> toBeRemoved = new HashSet<>();
+
+			for (AppointmentEntry entry : result) {
+				if (isBefore(entry, minDate)) {
+					toBeRemoved.add(entry);
+				}
+			}
+			result.removeAll(toBeRemoved);
+		}
+
 		return result;
 	}
 
+	private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
+
+	private boolean isBefore(AppointmentEntry entry, Calendar minDate) {
+		String entryDate = entry.getDay();
+		String beforeDate = DATE_FORMATTER.format(minDate.getTime());
+		if (entryDate.compareTo(beforeDate) < 0) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
 	int[]	dayColumns						 = new int[] { 3, 4, 5, 6, 7 };
 
 	int[]	weekStartRows					 = new int[] { 5, 23, 41, 59, 77, 95 };
diff --git a/appointment-import/src/test/java/smash/appointment/parse/AllTests.java b/appointment-import/src/test/java/smash/appointment/parse/AllTests.java
index 71c7e659a4d91942129cace99a9438c4c4e16d33..df5a093dc578b7660de0cdb9a6c9dff8d76aae5b 100644
--- a/appointment-import/src/test/java/smash/appointment/parse/AllTests.java
+++ b/appointment-import/src/test/java/smash/appointment/parse/AllTests.java
@@ -5,7 +5,8 @@ import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
-@SuiteClasses({ CellParserTest.class, //
+@SuiteClasses({ AppointmentDaoTest.class, //
+		CellParserTest.class, //
 		LihControlMappingParserTest.class, //
 		LihControlParserTest.class, //
 		PrcFlyingParserTest.class, //
@@ -14,6 +15,7 @@ import org.junit.runners.Suite.SuiteClasses;
 
 		SubjectDaoTest.class, //
 		SubjectParserTest.class, //
+		VisitTest.class, //
 		XlsxCalendarProcessorTest.class, //
 })
 
diff --git a/appointment-import/src/test/java/smash/appointment/parse/AppointmentDaoTest.java b/appointment-import/src/test/java/smash/appointment/parse/AppointmentDaoTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..82dba7faaf64b77c6ffda2e6d87bcca7244ce7fe
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/AppointmentDaoTest.java
@@ -0,0 +1,69 @@
+package smash.appointment.parse;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AppointmentDaoTest {
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void getVisits() {
+		Subject subject1 = new Subject("a", "b", "c", "d");
+		AppointmentEntry appointment = new AppointmentEntry();
+		appointment.setSubject(subject1);
+		appointment.setDay("2016-02-02");
+		appointment.addType(AppointmentType.LEVEL_A);
+		
+		AppointmentEntry appointment2 = new AppointmentEntry();
+		appointment2.setSubject(subject1);
+		appointment2.setDay("2016-02-02");
+		appointment2.addType(AppointmentType.LEVEL_B);
+		
+		AppointmentEntry appointment3 = new AppointmentEntry();
+		appointment3.setSubject(subject1);
+		appointment3.setDay("2011-02-02");
+		appointment3.addType(AppointmentType.LEVEL_A);
+		
+		AppointmentDao appointmentDao = new AppointmentDao();
+		appointmentDao.addAppointment(appointment);
+		appointmentDao.addAppointment(appointment2);
+		appointmentDao.addAppointment(appointment3);
+		assertEquals(2, appointmentDao.getVisits().size());
+	}
+
+	@Test
+	public void getVisits2() {
+		Subject subject1 = new Subject("a", "b", "c", "d");
+		Subject subject2 = new Subject("a1", "b1", "c1", "d1");
+		AppointmentEntry appointment = new AppointmentEntry();
+		appointment.setSubject(subject1);
+		appointment.setDay("2016-02-02");
+		appointment.addType(AppointmentType.LEVEL_A);
+		
+		AppointmentEntry appointment3 = new AppointmentEntry();
+		appointment3.setSubject(subject2);
+		appointment3.setDay("2016-02-02");
+		appointment3.addType(AppointmentType.LEVEL_B);
+		
+		AppointmentDao appointmentDao = new AppointmentDao();
+		appointmentDao.addAppointment(appointment);
+		appointmentDao.addAppointment(appointment3);
+		assertEquals(2, appointmentDao.getVisits().size());
+	}
+
+}
diff --git a/appointment-import/src/test/java/smash/appointment/parse/VisitTest.java b/appointment-import/src/test/java/smash/appointment/parse/VisitTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd3eb2d963d5699e12d1abc642d67070226e9a3a
--- /dev/null
+++ b/appointment-import/src/test/java/smash/appointment/parse/VisitTest.java
@@ -0,0 +1,48 @@
+package smash.appointment.parse;
+
+import static org.junit.Assert.*;
+
+import java.text.ParseException;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+public class VisitTest {
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testGetStartDate() {
+		Subject subject = new Subject("!", "", "4", "5");
+		Visit visit = new Visit(subject);
+		AppointmentEntry entry = new AppointmentEntry();
+		entry.setSubject(subject);
+		entry.setDay("2015-02-01 8:00");
+		visit.addAppointment(entry);
+		assertEquals("2015-02-01", visit.getStartDate());
+	}
+
+	@Test
+	public void testGetEndDate() throws ParseException {
+		Subject subject = new Subject("!", "", "4", "5");
+		Visit visit = new Visit(subject);
+		AppointmentEntry entry = new AppointmentEntry();
+		entry.setSubject(subject);
+		entry.setDay("2015-02-01 8:00");
+		visit.addAppointment(entry);
+		assertEquals("2015-05-01", visit.getEndDate());
+	}
+
+}
diff --git a/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java b/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java
index 7625586db5179fca20eea07077c17905f49e6e06..8e23b0a920bfd4ef3d4f0c218a767e502bae523b 100644
--- a/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java
+++ b/appointment-import/src/test/java/smash/appointment/parse/XlsxCalendarProcessorTest.java
@@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.io.FileNotFoundException;
+import java.util.Calendar;
 import java.util.List;
 
 import org.apache.log4j.Logger;
@@ -33,7 +34,7 @@ public class XlsxCalendarProcessorTest extends TestBase {
 
 	@Test
 	public void testReadExcel() throws Exception {
-		List<AppointmentEntry> entries = processor.processExcel("testFiles/calendarExample.xlsx");
+		List<AppointmentEntry> entries = processor.processExcel("testFiles/calendarExample.xlsx", Calendar.getInstance());
 		assertTrue(entries.size() > 0);
 	}
 
diff --git a/appointment-import/testFiles/calendarExample.xlsx b/appointment-import/testFiles/calendarExample.xlsx
index e6ef090b5834afa3e0a9a414c96c3a37c8ae253f..b8a0e42b59245f10692d9739ade2a0e8e4cc8b03 100644
Binary files a/appointment-import/testFiles/calendarExample.xlsx and b/appointment-import/testFiles/calendarExample.xlsx differ