func (conf *ServerNodeConfiguration) SaveConfiguration() error {
	oldFilename := path.Join(conf.root_path, CONFIG_SUB_DIRECTORY, CONFIG_FILENAME_OLD)
	currentFilename := path.Join(conf.root_path, CONFIG_SUB_DIRECTORY, CONFIG_FILENAME_CURRENT)
	newFilename := path.Join(conf.root_path, CONFIG_SUB_DIRECTORY, CONFIG_FILENAME_NEW)
	err := os.Remove(newFilename)
	if err != nil && !os.IsNotExist(err) {
		conf_log("Error cleaning up any old new save file: %v\n", err)
		return err
	}
	data, err := json.Marshal(conf)
	if err != nil {
		conf_log("Error marshalling configuration to json: %v\n", err)
		return err
	}
	file, err := os.Create(newFilename)
	if err != nil {
		conf_log("Error persisting config file: %v\n", err)
		return err
	}
	if _, err = file.Write(data); err != nil {
		conf_log("Error writing config data to file: %v\n", err)
		return err
	}
	if err = file.Close(); err != nil {
		conf_log("Error closing configuration file: %v\n", err)
		return err
	}
	err = os.Remove(oldFilename)
	if err != nil && !os.IsNotExist(err) {
		conf_log("Error cleaning up any old save file: %v\n", err)
		return err
	}
	err = os.Rename(currentFilename, oldFilename)
	if err != nil && !os.IsNotExist(err) {
		conf_log("Error moving current config file to old: %v\n", err)
		return err
	}
	if err = os.Rename(newFilename, currentFilename); err != nil {
		conf_log("Error moving new configuration file into place: %v\n", err)
		return err
	}
	return nil
}
/*
SaveConfiguration saves the configuration file as JSON in the conf.root_path

Logic:

1 - Delete the config.new file if it already exists.
2 - Create the new confing.new file.
3 - Delete the config.old file if it already exists.
4 - Move the existing confing.cfg file to config.old
5 - Move the new config.new file to config.cfg
package server
import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"log"
	"os"
	"path"
	"time"
)
var ERR_INCORRECT_CLUSTER_ID = errors.New("Incorrect cluster ID")
var ERR_MISSING_CONFIG_NON_EMPTY_DIR = errors.New("Configuration files not found or could not be read, but the given directory is not empty and so no new configuration created.")
type ConfigChangeType int64
var conf_log = log.New(os.Stderr, "Config: ", log.LstdFlags).Printf
const (
	CNF_Set_Peers ConfigChangeType = 1 << iota
	CNF_Set_Topic
	CNF_Remove_Topic
)
const CONFIG_SUB_DIRECTORY = "Config"
const CONFIG_FILENAME_CURRENT = "config.cfg"
const CONFIG_FILENAME_OLD = "config.old"
const CONFIG_FILENAME_NEW = "config.new"
const DATA_SUB_DIRECTORY = "Data"
type ConfigTopic struct {
	Name              string
	SegmentSize       int
	SegmentCleanupAge time.Duration
}
func (ct *ConfigTopic) String() string {
	return ct.Name
}
func GetDefaultTopicConfiguration() ConfigTopic {
	conf := ConfigTopic{}
	conf.SegmentSize = 1024  
	return conf
}
type ConfigTopics map[string]ConfigTopic
func (topics ConfigTopics) Contains(topicName string) bool {
	_, ok := topics[topicName]
	return ok
}
type ConfigPeers []string
func (peers ConfigPeers) Excluding(me string) ConfigPeers {
	newList := make(ConfigPeers, 0, len(peers))
	for _, peer := range peers {
		if peer != me {
			newList = append(newList, peer)
		}
	}
	return newList
}
func (peers ConfigPeers) Contains(peer string) bool {
	for _, p := range peers {
		if p == peer {
			return true
		}
	}
	return false
}
type ServerNodeConfiguration struct {
	Cluster_ID string
	Scope ConfigChangeType
	Peers ConfigPeers
	Topics ConfigTopics
	Data_Paths []string
	root_path string
}
func GetEmptyConfiguration() *ServerNodeConfiguration {
	conf := &ServerNodeConfiguration{Topics: make(ConfigTopics)}
	return conf
}