diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
new file mode 100644
index 0000000..58b446c
--- /dev/null
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2014-2015 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.store.trivial;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.Bandwidth;
+import org.onlab.util.PositionalParameterStringFormatter;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.Link;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.resource.link.BandwidthResource;
+import org.onosproject.net.resource.link.BandwidthResourceAllocation;
+import org.onosproject.net.resource.link.LambdaResource;
+import org.onosproject.net.resource.link.LambdaResourceAllocation;
+import org.onosproject.net.resource.link.LinkResourceAllocations;
+import org.onosproject.net.resource.link.LinkResourceEvent;
+import org.onosproject.net.resource.link.LinkResourceStore;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceAllocationException;
+import org.onosproject.net.resource.ResourceType;
+import org.slf4j.Logger;
+
+import com.google.common.collect.ImmutableList;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages link resources using trivial in-memory structures implementation.
+ */
+@Component(immediate = true)
+@Service
+public class SimpleLinkResourceStore implements LinkResourceStore {
+    private static final BandwidthResource DEFAULT_BANDWIDTH = new BandwidthResource(Bandwidth.mbps(1_000));
+    private final Logger log = getLogger(getClass());
+
+    private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
+    private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
+    private Map<Link, Set<ResourceAllocation>> freeResources;
+
+    @Activate
+    public void activate() {
+        linkResourceAllocationsMap = new HashMap<>();
+        allocatedResources = new HashMap<>();
+        freeResources = new HashMap<>();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    /**
+     * Returns free resources for a given link obtaining from topology
+     * information.
+     *
+     * @param link the target link
+     * @return free resources
+     */
+    private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
+        Annotations annotations = link.annotations();
+        Set<ResourceAllocation> allocations = new HashSet<>();
+
+        try {
+            int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
+            for (int i = 1; i <= waves; i++) {
+                allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i)));
+            }
+        } catch (NumberFormatException e) {
+            log.debug("No optical.wave annotation on link %s", link);
+        }
+
+        BandwidthResource bandwidth = DEFAULT_BANDWIDTH;
+        try {
+            bandwidth = new BandwidthResource(
+                    Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH)))));
+        } catch (NumberFormatException e) {
+            log.debug("No bandwidth annotation on link %s", link);
+        }
+        allocations.add(
+                new BandwidthResourceAllocation(bandwidth));
+        return allocations;
+    }
+
+    /**
+     * Finds and returns {@link BandwidthResourceAllocation} object from a given
+     * set.
+     *
+     * @param freeRes a set of ResourceAllocation object.
+     * @return {@link BandwidthResourceAllocation} object if found, otherwise
+     *         {@link BandwidthResourceAllocation} object with 0 bandwidth
+     *
+     */
+    private synchronized BandwidthResourceAllocation getBandwidth(
+            Set<ResourceAllocation> freeRes) {
+        for (ResourceAllocation res : freeRes) {
+            if (res.type() == ResourceType.BANDWIDTH) {
+                return (BandwidthResourceAllocation) res;
+            }
+        }
+        return new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.bps(0)));
+    }
+
+    /**
+     * Subtracts given resources from free resources for given link.
+     *
+     * @param link the target link
+     * @param allocations the resources to be subtracted
+     */
+    private synchronized void subtractFreeResources(Link link,
+            LinkResourceAllocations allocations) {
+        // TODO Use lock or version for updating freeResources.
+        checkNotNull(link);
+        Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
+        Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
+        for (ResourceAllocation res : subRes) {
+            switch (res.type()) {
+            case BANDWIDTH:
+                BandwidthResourceAllocation ba = getBandwidth(freeRes);
+                double requestedBandwidth =
+                        ((BandwidthResourceAllocation) res).bandwidth().toDouble();
+                double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
+                if (newBandwidth < 0.0) {
+                    throw new ResourceAllocationException(
+                            PositionalParameterStringFormatter.format(
+                            "Unable to allocate bandwidth for link {} "
+                            + "requested amount is {} current allocation is {}",
+                                    link,
+                                    requestedBandwidth,
+                                    ba));
+                }
+                freeRes.remove(ba);
+                freeRes.add(new BandwidthResourceAllocation(
+                        new BandwidthResource(Bandwidth.bps(newBandwidth))));
+                break;
+            case LAMBDA:
+                final boolean lambdaAvailable = freeRes.remove(res);
+                if (!lambdaAvailable) {
+                    int requestedLambda =
+                            ((LambdaResourceAllocation) res).lambda().toInt();
+                    throw new ResourceAllocationException(
+                            PositionalParameterStringFormatter.format(
+                                    "Unable to allocate lambda for link {} lambda is {}",
+                                    link,
+                                    requestedLambda));
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        freeResources.put(link, freeRes);
+
+    }
+
+    /**
+     * Adds given resources to free resources for given link.
+     *
+     * @param link the target link
+     * @param allocations the resources to be added
+     */
+    private synchronized void addFreeResources(Link link,
+            LinkResourceAllocations allocations) {
+        // TODO Use lock or version for updating freeResources.
+        Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
+        Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
+        for (ResourceAllocation res : addRes) {
+            switch (res.type()) {
+            case BANDWIDTH:
+                BandwidthResourceAllocation ba = getBandwidth(freeRes);
+                double requestedBandwidth =
+                        ((BandwidthResourceAllocation) res).bandwidth().toDouble();
+                double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
+                freeRes.remove(ba);
+                freeRes.add(new BandwidthResourceAllocation(
+                        new BandwidthResource(Bandwidth.bps(newBandwidth))));
+                break;
+            case LAMBDA:
+                checkState(freeRes.add(res));
+                break;
+            default:
+                break;
+            }
+        }
+        freeResources.put(link, freeRes);
+    }
+
+    @Override
+    public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
+        checkNotNull(link);
+        Set<ResourceAllocation> freeRes = freeResources.get(link);
+        if (freeRes == null) {
+            freeRes = readOriginalFreeResources(link);
+        }
+
+        return freeRes;
+    }
+
+    @Override
+    public synchronized void allocateResources(LinkResourceAllocations allocations) {
+        checkNotNull(allocations);
+        linkResourceAllocationsMap.put(allocations.intentId(), allocations);
+        for (Link link : allocations.links()) {
+            subtractFreeResources(link, allocations);
+            Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
+            if (linkAllocs == null) {
+                linkAllocs = new HashSet<>();
+            }
+            linkAllocs.add(allocations);
+            allocatedResources.put(link, linkAllocs);
+        }
+    }
+
+    @Override
+    public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
+        checkNotNull(allocations);
+        linkResourceAllocationsMap.remove(allocations.intentId());
+        for (Link link : allocations.links()) {
+            addFreeResources(link, allocations);
+            Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
+            if (linkAllocs == null) {
+                log.error("Missing resource allocation.");
+            } else {
+                linkAllocs.remove(allocations);
+            }
+            allocatedResources.put(link, linkAllocs);
+        }
+
+        final List<LinkResourceAllocations> releasedResources =
+                ImmutableList.of(allocations);
+
+        return new LinkResourceEvent(
+                LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
+                releasedResources);
+    }
+
+    @Override
+    public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
+        checkNotNull(intentId);
+        return linkResourceAllocationsMap.get(intentId);
+    }
+
+    @Override
+    public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
+        checkNotNull(link);
+        Set<LinkResourceAllocations> result = allocatedResources.get(link);
+        if (result == null) {
+            result = Collections.emptySet();
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    @Override
+    public synchronized Iterable<LinkResourceAllocations> getAllocations() {
+        return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
+    }
+
+
+}
