diff --git a/calendar/pom.xml b/calendar/pom.xml
new file mode 100644
index 0000000..32abb2b
--- /dev/null
+++ b/calendar/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2014 Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-calendar</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>ONOS simple calendaring REST interface for intents</description>
+
+    <properties>
+        <web.context>/onos/calendar</web.context>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey.jersey-test-framework</groupId>
+            <artifactId>jersey-test-framework-core</artifactId>
+            <version>1.18.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey.jersey-test-framework</groupId>
+            <artifactId>jersey-test-framework-grizzly2</artifactId>
+            <version>1.18.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+
+    <dependency>
+      <groupId>org.onosproject</groupId>
+      <artifactId>onlab-thirdparty</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.onosproject</groupId>
+      <artifactId>onlab-misc</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.onosproject</groupId>
+      <artifactId>onlab-junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.onosproject</groupId>
+      <artifactId>onos-cli</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.shell</groupId>
+      <artifactId>org.apache.karaf.shell.console</artifactId>
+    </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            org.slf4j,
+                            org.osgi.framework,
+                            javax.ws.rs,javax.ws.rs.core,
+                            com.sun.jersey.api.core,
+                            com.sun.jersey.spi.container.servlet,
+                            com.sun.jersey.server.impl.container.servlet,
+                            org.onlab.packet.*,
+                            org.onlab.rest.*,
+                            org.onosproject.*
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/calendar/src/main/java/org/onosproject/calendar/BandwidthCalendarResource.java b/calendar/src/main/java/org/onosproject/calendar/BandwidthCalendarResource.java
new file mode 100644
index 0000000..ac02290
--- /dev/null
+++ b/calendar/src/main/java/org/onosproject/calendar/BandwidthCalendarResource.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.calendar;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.rest.BaseResource;
+import org.onlab.util.Tools;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.ConnectivityIntent;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.TwoWayP2PIntent;
+import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.intent.constraint.LatencyConstraint;
+import org.onosproject.net.resource.Bandwidth;
+import org.slf4j.Logger;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
+import static org.onosproject.net.intent.IntentState.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Web resource for triggering calendared intents.
+ */
+@javax.ws.rs.Path("intent")
+public class BandwidthCalendarResource extends BaseResource {
+
+    private static final Logger log = getLogger(BandwidthCalendarResource.class);
+    private static final long TIMEOUT = 10; // seconds
+
+    private static final String INVALID_PARAMETER = "INVALID_PARAMETER\n";
+    private static final String OPERATION_INSTALLED = "INSTALLED\n";
+    private static final String OPERATION_FAILED = "FAILED\n";
+    private static final String OPERATION_WITHDRAWN = "WITHDRAWN\n";
+
+    /**
+     * Setup a bi-directional path with constraints between switch to switch.
+     * Switch is identified by DPID.
+     *
+     * @param src the path source (DPID or hostID)
+     * @param dst the path destination (DPID or hostID)
+     * @param srcPort the source port (-1 if src/dest is a host)
+     * @param dstPort the destination port (-1 if src/dest is a host)
+     * @param bandwidth the bandwidth (mbps) requirement for the path
+     * @param latency the latency (micro sec) requirement for the path
+     * @return intent key if successful,
+     *         server error message or "FAILED" if failed to create or submit intent
+     */
+    @javax.ws.rs.Path("/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}/{latency}")
+    @POST
+    // TODO could allow applications to provide optional key
+    // ... if you do, you will need to change from LongKeys to StringKeys
+    public Response setupPath(@PathParam("src") String src,
+                              @PathParam("dst") String dst,
+                              @PathParam("srcPort") String srcPort,
+                              @PathParam("dstPort") String dstPort,
+                              @PathParam("bandwidth") String bandwidth,
+                              @PathParam("latency") String latency) {
+
+        log.info("Path Constraints: Src = {} SrcPort = {} Dest = {} DestPort = {} " +
+                          "BW = {} latency = {}",
+                 src, srcPort, dst, dstPort, bandwidth, latency);
+
+        if (src == null || dst == null || srcPort == null || dstPort == null) {
+            return Response.ok(INVALID_PARAMETER).build();
+        }
+
+        Long bandwidthL = 0L;
+        Long latencyL = 0L;
+        try {
+            bandwidthL = Long.parseLong(bandwidth, 10);
+            latencyL = Long.parseLong(latency, 10);
+        } catch (Exception e) {
+            return Response.ok(INVALID_PARAMETER).build();
+        }
+
+        Intent intent = createIntent(null, src, dst, srcPort, dstPort, bandwidthL, latencyL);
+        try {
+            if (submitIntent(intent)) {
+                return Response.ok(intent.key() + "\n").build();
+            } else {
+                return Response.ok(OPERATION_FAILED).build();
+            }
+        } catch (Exception e) {
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+        }
+    }
+
+    /**
+     * Modify a bi-directional path's bandwidth.
+     *
+     * @param intentKey the path intent key
+     * @param src the path source (DPID or hostID)
+     * @param dst the path destination (DPID or hostID)
+     * @param srcPort the source port (-1 if src/dest is a host)
+     * @param dstPort the destination port (-1 if src/dest is a host)
+     * @param bandwidth the bandwidth (mbps) requirement for the path
+     * @return Intent state, "INSTALLED", if successful,
+     *         server error message or "FAILED" if failed to modify any direction intent
+     */
+    @javax.ws.rs.Path("/{intentKey}/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}")
+    @PUT
+    public Response modifyBandwidth(@PathParam("intentKey") String intentKey,
+                                    @PathParam("src") String src,
+                                    @PathParam("dst") String dst,
+                                    @PathParam("srcPort") String srcPort,
+                                    @PathParam("dstPort") String dstPort,
+                                    @PathParam("bandwidth") String bandwidth) {
+
+        log.info("Modify bw for intentKey = {}; src = {}; dst = {};" +
+                         "srcPort = {}; dstPort = {}; with new bandwidth = {}",
+                 intentKey, src, dst, srcPort, dstPort, bandwidth);
+
+        if (src == null || dst == null || srcPort == null || dstPort == null) {
+            return Response.ok(INVALID_PARAMETER).build();
+        }
+
+        Long bandwidthL = 0L;
+        try {
+            bandwidthL = Long.parseLong(bandwidth, 10);
+        } catch (Exception e) {
+            return Response.ok(INVALID_PARAMETER).build();
+        }
+
+        IntentService service = get(IntentService.class);
+        Intent originalIntent
+                = service.getIntent(Key.of(Tools.fromHex(intentKey.replace("0x", "")), appId()));
+
+        if (originalIntent == null) {
+            return Response.status(Response.Status.NOT_FOUND).build();
+        }
+
+        // get the latency constraint from the original intent
+        Long latencyL = 0L;
+        if (originalIntent instanceof ConnectivityIntent) {
+            ConnectivityIntent connectivityIntent = (ConnectivityIntent) originalIntent;
+            for (Constraint constraint : connectivityIntent.constraints()) {
+                if (constraint instanceof LatencyConstraint) {
+                    latencyL = ((LatencyConstraint) constraint).latency().get(ChronoUnit.MICROS);
+                }
+            }
+        }
+
+        Intent newIntent = createIntent(originalIntent.key(), src, dst,
+                                        srcPort, dstPort, bandwidthL, latencyL);
+        try {
+            if (submitIntent(newIntent)) {
+                return Response.ok(OPERATION_INSTALLED).build();
+            } else {
+                return Response.ok(OPERATION_FAILED).build();
+            }
+        } catch (Exception e) {
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+        }
+    }
+
+
+    /**
+     * Create an Intent for a bidirectional path with constraints.
+     *
+     * @param key optional intent key
+     * @param src the path source (DPID or hostID)
+     * @param dst the path destination (DPID or hostID)
+     * @param srcPort the source port (-1 if src/dest is a host)
+     * @param dstPort the destination port (-1 if src/dest is a host)
+     * @param bandwidth the bandwidth (mbps) requirement for the path
+     * @param latency the latency (micro sec) requirement for the path
+     * @return the appropriate intent
+     */
+    private Intent createIntent(Key key,
+                                String src,
+                                String dst,
+                                String srcPort,
+                                String dstPort,
+                                Long bandwidth,
+                                Long latency) {
+
+        TrafficSelector selector = buildTrafficSelector();
+        TrafficTreatment treatment = builder().build();
+
+        final Constraint constraintBandwidth =
+                new BandwidthConstraint(Bandwidth.mbps(bandwidth));
+        final Constraint constraintLatency =
+                new LatencyConstraint(Duration.of(latency, ChronoUnit.MICROS));
+        final List<Constraint> constraints = new LinkedList<>();
+
+        constraints.add(constraintBandwidth);
+        constraints.add(constraintLatency);
+
+        if (srcPort.equals("-1")) {
+            HostId srcPoint = HostId.hostId(src);
+            HostId dstPoint = HostId.hostId(dst);
+            return new HostToHostIntent(appId(), key, srcPoint, dstPoint,
+                                        selector, treatment, constraints);
+        } else {
+            ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort));
+            ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort));
+            return new TwoWayP2PIntent(appId(), key, srcPoint, dstPoint,
+                                       selector, treatment, constraints);
+        }
+    }
+
+
+    /**
+     * Synchronously submits an intent to the Intent Service.
+     *
+     * @param intent intent to submit
+     * @return true if operation succeed, false otherwise
+     */
+    private boolean submitIntent(Intent intent)
+        throws InterruptedException {
+        IntentService service = get(IntentService.class);
+
+        CountDownLatch latch = new CountDownLatch(1);
+        InternalIntentListener listener = new InternalIntentListener(intent, service, latch);
+        service.addListener(listener);
+        service.submit(intent);
+        log.info("Submitted Calendar App intent and waiting: {}", intent);
+        if (latch.await(TIMEOUT, TimeUnit.SECONDS) &&
+                listener.getState() == INSTALLED) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Remove a bi-directional path with created intent key.
+     *
+     * @param intentKey the string key for the intent to remove
+     * @return Intent state, "WITHDRAWN", if successful,
+     *         server error message or FAILED" if any direction intent remove failed
+     */
+    @javax.ws.rs.Path("/{intentKey}")
+    @DELETE
+    public Response removePath(@PathParam("intentKey") String intentKey) {
+
+        log.info("Receiving tear down request for {}", intentKey);
+
+        if (intentKey == null) {
+            return Response.ok(INVALID_PARAMETER).build();
+        }
+
+        IntentService service = get(IntentService.class);
+        Intent intent = service.getIntent(Key.of(Tools.fromHex(intentKey.replace("0x", "")), appId()));
+
+        if (intent == null) {
+            return Response.status(Response.Status.NOT_FOUND).build();
+        }
+
+        try {
+            if (withdrawIntent(intent)) {
+                return Response.ok(OPERATION_WITHDRAWN).build();
+            } else {
+                return Response.ok(OPERATION_FAILED).build();
+            }
+        } catch (Exception e) {
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+        }
+    }
+
+    /**
+     * Synchronously withdraws an intent to the Intent Service.
+     *
+     * @param intent intent to submit
+     * @return true if operation succeed, false otherwise
+     */
+    private boolean withdrawIntent(Intent intent)
+            throws InterruptedException {
+        IntentService service = get(IntentService.class);
+
+        CountDownLatch latch = new CountDownLatch(1);
+        InternalIntentListener listener = new InternalIntentListener(intent, service, latch);
+        service.addListener(listener);
+        service.withdraw(intent);
+        log.info("Withdrawing intent and waiting: {}", intent);
+        if (latch.await(TIMEOUT, TimeUnit.SECONDS) &&
+                listener.getState() == WITHDRAWN) {
+            return true;
+        }
+        return false;
+    }
+
+
+    private static TrafficSelector buildTrafficSelector() {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        Short ethType = Ethernet.TYPE_IPV4;
+
+        selectorBuilder.matchEthType(ethType);
+
+        return selectorBuilder.build();
+    }
+
+    private static DeviceId deviceId(String dpid) {
+        return DeviceId.deviceId(URI.create("of:" + dpid));
+    }
+
+    protected ApplicationId appId() {
+        return get(CoreService.class).registerApplication("org.onosproject.calendar");
+    }
+
+    // Auxiliary listener to wait until the given intent reaches the installed or failed states.
+    private final class InternalIntentListener implements IntentListener {
+        private final Intent intent;
+        private final IntentService service;
+        private final CountDownLatch latch;
+        private IntentState state;
+
+        private InternalIntentListener(Intent intent, IntentService service,
+                                       CountDownLatch latch) {
+            this.intent = intent;
+            this.service = service;
+            this.latch = latch;
+        }
+
+        @Override
+        public void event(IntentEvent event) {
+            if (event.subject().equals(intent)) {
+                state = service.getIntentState(intent.key());
+                if (state == INSTALLED || state == FAILED || state == WITHDRAWN) {
+                    latch.countDown();
+                    service.removeListener(this);
+                }
+            }
+        }
+
+        public IntentState getState() {
+            return state;
+        }
+    }
+}
diff --git a/calendar/src/main/java/org/onosproject/calendar/package-info.java b/calendar/src/main/java/org/onosproject/calendar/package-info.java
new file mode 100644
index 0000000..8cd17a9
--- /dev/null
+++ b/calendar/src/main/java/org/onosproject/calendar/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Application providing integration between OSCARS and ONOS intent
+ * framework via REST API.
+ */
+package org.onosproject.calendar;
diff --git a/calendar/src/main/webapp/WEB-INF/web.xml b/calendar/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..1a7de2b
--- /dev/null
+++ b/calendar/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2014 Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>ONOS GUI</display-name>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+            <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+        </init-param>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.classnames</param-name>
+            <param-value>org.onosproject.calendar.BandwidthCalendarResource</param-value>
+        </init-param>
+        <load-on-startup>10</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
