[XAPID-1074] add offline mode
diff --git a/apigee_sync.go b/apigee_sync.go
index 10745de..a78b0ab 100644
--- a/apigee_sync.go
+++ b/apigee_sync.go
@@ -36,6 +36,9 @@
  *  Then, poll for changes
  */
 func bootstrap() {
+	if isOfflineMode && apidInfo.LastSnapshot == "" {
+		log.Panic("Offline mode requires existent snapshot info in default DB.")
+	}
 
 	if apidInfo.LastSnapshot != "" {
 		snapshot := startOnLocalSnapshot(apidInfo.LastSnapshot)
diff --git a/changes.go b/changes.go
index 993613f..6358307 100644
--- a/changes.go
+++ b/changes.go
@@ -362,3 +362,14 @@
 	}
 	return nil
 }
+
+type offlineChangeManager struct {
+}
+
+func (o *offlineChangeManager) close() <-chan bool {
+	c := make(chan bool, 1)
+	c <- true
+	return c
+}
+
+func (o *offlineChangeManager) pollChangeWithBackoff() {}
diff --git a/init.go b/init.go
index 1ad67fd..6b1be34 100644
--- a/init.go
+++ b/init.go
@@ -22,6 +22,7 @@
 	"time"
 
 	"github.com/30x/apid-core"
+	"strings"
 )
 
 const (
@@ -34,14 +35,21 @@
 	configApidClusterId       = "apigeesync_cluster_id"
 	configSnapshotProtocol    = "apigeesync_snapshot_proto"
 	configName                = "apigeesync_instance_name"
-	ApigeeSyncEventSelector   = "ApigeeSync"
-
+	configOnlineMode          = "apigeesync_online"
 	// special value - set by ApigeeSync, not taken from configuration
 	configApidInstanceID = "apigeesync_apid_instance_id"
 	// This will not be needed once we have plugin handling tokens.
 	configBearerToken = "apigeesync_bearer_token"
 )
 
+const (
+	ApigeeSyncEventSelector = "ApigeeSync"
+)
+
+const (
+	offlineMode = "offline"
+)
+
 var (
 	/* All set during plugin initialization */
 	log                 apid.LogService
@@ -54,6 +62,7 @@
 	apidChangeManager   changeManager
 	apidSnapshotManager snapShotManager
 	httpclient          *http.Client
+	isOfflineMode       bool
 
 	/* Set during post plugin initialization
 	 * set this as a default, so that it's guaranteed to be valid even if postInitPlugins isn't called
@@ -77,6 +86,7 @@
 func initConfigDefaults() {
 	config.SetDefault(configPollInterval, 120*time.Second)
 	config.SetDefault(configSnapshotProtocol, "sqlite")
+	config.SetDefault(configOnlineMode, "online")
 	name, errh := os.Hostname()
 	if (errh != nil) && (len(config.GetString(configName)) == 0) {
 		log.Errorf("Not able to get hostname for kernel. Please set '%s' property in config", configName)
@@ -127,15 +137,24 @@
 }
 
 func createManagers() {
-	apidSnapshotManager = createSnapShotManager()
-	apidChangeManager = createChangeManager()
+	if isOfflineMode {
+		apidSnapshotManager = &offlineSnapshotManager{}
+		apidChangeManager = &offlineChangeManager{}
+	} else {
+		apidSnapshotManager = createSnapShotManager()
+		apidChangeManager = createChangeManager()
+	}
+
 	apidTokenManager = createSimpleTokenManager()
 }
 
 func checkForRequiredValues() error {
+	required := []string{configProxyServerBaseURI, configConsumerKey, configConsumerSecret}
+	if !isOfflineMode {
+		required = append(required, configSnapServerBaseURI, configChangeServerBaseURI)
+	}
 	// check for required values
-	for _, key := range []string{configProxyServerBaseURI, configConsumerKey, configConsumerSecret,
-		configSnapServerBaseURI, configChangeServerBaseURI} {
+	for _, key := range required {
 		if !config.IsSet(key) {
 			return fmt.Errorf("Missing required config value: %s", key)
 		}
@@ -160,6 +179,10 @@
 	config = services.Config()
 	initConfigDefaults()
 
+	if strings.EqualFold(config.GetString(configOnlineMode), offlineMode) {
+		isOfflineMode = true
+	}
+
 	err := checkForRequiredValues()
 	if err != nil {
 		return err
diff --git a/snapshot.go b/snapshot.go
index 3040b24..90c03a2 100644
--- a/snapshot.go
+++ b/snapshot.go
@@ -343,3 +343,24 @@
 func handleSnapshotServerError(err error) {
 	log.Debugf("Error connecting to snapshot server: %v", err)
 }
+
+type offlineSnapshotManager struct {
+}
+
+func (o *offlineSnapshotManager) close() <-chan bool {
+	c := make(chan bool, 1)
+	c <- true
+	return c
+}
+
+func (o *offlineSnapshotManager) downloadBootSnapshot() {}
+
+func (o *offlineSnapshotManager) storeBootSnapshot(snapshot *common.Snapshot) {}
+
+func (o *offlineSnapshotManager) downloadDataSnapshot() {}
+
+func (o *offlineSnapshotManager) storeDataSnapshot(snapshot *common.Snapshot) {}
+
+func (o *offlineSnapshotManager) downloadSnapshot(isBoot bool, scopes []string, snapshot *common.Snapshot) error {
+	return nil
+}