diff --git a/includes/class-wp-push-syndication-server.php b/includes/class-wp-push-syndication-server.php
new file mode 100644
index 0000000000000000000000000000000000000000..678083d14c9b5b18e773611c29d3435733f7b7a1
--- /dev/null
+++ b/includes/class-wp-push-syndication-server.php
@@ -0,0 +1,1086 @@
+<?php
+
+// @TODO define a new capability to push syndicate
+// @TODO check add add_settings_field args
+// @TODO add help using contextual_help
+// @TODO mark helper functions as private?
+// @TODO check sites are publicly queryable
+// @TODO add options to retry delete_error_sites
+
+require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
+
+class Push_Syndication_Server {
+
+    private $push_syndicate_settings;
+    private $push_syndicate_tranports;
+
+    function __construct() {
+
+        // get plugin settings
+        $this->push_syndicate_settings = get_option( 'push_syndicate_settings' );
+
+        // initialization
+        add_action( 'init', array( &$this, 'init' ) );
+        add_action( 'admin_init', array( &$this, 'admin_init' ) );
+
+        // plugin settings submenus
+        add_action( 'admin_menu', array( &$this, 'register_syndicate_settings' ) );
+
+        // defining sites
+        add_action( 'save_post', array( &$this, 'save_site_settings' ) );
+
+        // loading necessary styles and scripts
+        add_action( 'admin_enqueue_scripts', array( &$this, 'load_scripts_and_styles' ) );
+
+        // filter admin notices in custom post types
+        add_filter( 'post_updated_messages', array( &$this, 'push_syndicate_admin_messages' ) );
+
+        // syndicating content
+        add_action( 'add_meta_boxes', array( &$this, 'add_post_metaboxes' ) );
+        add_action( 'save_post', array( &$this, 'save_syndicate_settings' ) );
+        add_action( 'wp_trash_post', array( &$this, 'delete_slave_posts' ) );
+
+        // firing a cron job
+        add_action( 'transition_post_status', array(&$this, 'schedule_syndicate_content_cron') );
+
+        // cron hooks
+        add_action( 'syn_syndicate_content', array(&$this, 'syndicate_content') );
+        add_action( 'syn_delete_content', array(&$this, 'delete_content') );
+        add_action( 'syn_syndicate_options', array(&$this, 'syndicate_options') );
+
+    }
+
+    public function init() {
+
+        register_post_type(
+            'syn_site',
+            array(
+                'labels' => array(
+                    'name'              => __( 'Sites' ),
+                    'singular_name'     => __( 'Site' ),
+                    'add_new'           => __( 'Add Site' ),
+                    'add_new_item'      => __( 'Add New Site' ),
+                    'edit_item'         => __( 'Edit Site' ),
+                    'new_item'          => __( 'New Site' ),
+                    'view_item'         => __( 'View Site' ),
+                    'search_items'      => __( 'Search Sites' ),
+                ),
+                'description'           => __( 'Sites in the netowrk' ),
+                'public'                => false,
+                'show_ui'               => true,
+                'publicly_queryable'    => false,
+                'exclude_from_search'   => false,
+                'menu_position'         => 80,
+                // @TODO we need a menu icon here
+                'hierarchical'          => false, // @TODO check this
+                'query_var'             => true,
+                // @TODO match capabilities with custom capabilities
+                'supports'              => array( 'title' ),
+                'can_export'            => true,
+                'register_meta_box_cb'  => array( &$this, 'site_metaboxes' ),
+            )
+        );
+
+        register_taxonomy(
+            'syn_sitegroup',
+            array( 'syn_site' ),
+            array(
+                'labels' => array(
+                    'name'              => __( 'Site Groups' ),
+                    'singular_name'     => __( 'Site Group' ),
+                    'search_items'      => __( 'Search Site Groups' ),
+                    'popular_items'     => __( 'Popular Site Groups' ),
+                    'all_items'         => __( 'All Site Groups' ),
+                    'parent_item'       => __( 'Parent Site Group' ),
+                    'parent_item_colon' => __( 'Parent Site Group' ),
+                    'edit_item'         => __( 'Edit Site Group' ),
+                    'update_item'       => __( 'Update Site Group' ),
+                    'add_new_item'      => __( 'Add New Site Group' ),
+                    'new_item_name'     => __( 'New Site Group Name' ),
+
+                ),
+                'public'                => false,
+                'show_ui'               => true,
+                'show_tagcloud'         => false,
+                'show_in_nav_menus'     => false,
+                'hierarchical'          => true,
+                // @TODO match capabilities with custom capabilities
+                'rewrite'               => false,
+            )
+        );
+
+
+    }
+
+    public function admin_init() {
+
+        // @TODO define more parameters
+        $this->push_syndicate_tranports = array(
+            'wp_xmlrpc'    => array(
+                'name'  => 'WordPress XMLRPC',
+                'path'  => ''
+            ),
+            'wp_rest'      => array(
+                'name'  => 'WordPress.com REST',
+                'path'  => ''
+            ),
+        );
+
+        $this->push_syndicate_tranports = apply_filters( 'push_syndicate_transports', $this->push_syndicate_tranports );
+
+        // register styles and scripts
+        wp_register_style( 'syn_sites', plugins_url( 'css/sites.css', __FILE__ ) );
+
+        register_setting( 'push_syndicate_settings', 'push_syndicate_settings', array( &$this, 'push_syndicate_settings_validate' ) );
+
+        // if no post types are selected set post by default
+        if( empty( $this->push_syndicate_settings['selected_post_types'] )  ) {
+            $this->push_syndicate_settings['selected_post_types'] = array( 'post' );
+            update_option( 'push_syndicate_settings', $this->push_syndicate_settings );
+        }
+
+    }
+
+    /*******     STYLES AND SCRIPTS   ********/
+    public function load_scripts_and_styles( $hook ) {
+
+        global $typenow;
+        if( $hook == 'edit.php' && $typenow == 'syn_site') {
+            wp_enqueue_style( 'syn_sites' );
+        }
+
+    }
+
+    /*******     PLUGIN SETTINGS       *******/
+    public function push_syndicate_settings_validate( $raw_settings ) {
+
+        $settings = array();
+        $settings['client_id'] = sanitize_text_field( $raw_settings['client_id'] );
+        $settings['client_secret'] = sanitize_text_field( $raw_settings['client_secret'] );
+        $settings['selected_post_types'] = $raw_settings['selected_post_types'];
+        $settings['delete_pushed_posts'] = $raw_settings['delete_pushed_posts'];
+
+        return $raw_settings;
+
+    }
+
+    public function register_syndicate_settings() {
+        add_submenu_page( 'options-general.php', __( 'Push Syndicate Settings'), __( 'Push Syndicate Settings' ), 'manage_options', 'push-syndicate-settings', array( &$this, 'display_syndicate_settings' ) );
+        add_submenu_page( 'edit.php?post_type=syn_site', __( 'Site Options'), __( 'Site Options' ), 'manage_options', 'push-syndicate-site-options', array( &$this, 'display_site_options' ) );
+    }
+
+    public function display_syndicate_settings() {
+
+        add_settings_section( 'push_syndicate_post_types', esc_html__(' Post Type Configuration '), array( &$this, 'display_push_post_types_description' ), 'push_syndicate_post_types');
+        add_settings_field( 'post_type_selection', esc_html__(' select post types '), array( &$this, 'display_post_types_selection' ), 'push_syndicate_post_types', 'push_syndicate_post_types' );
+
+        add_settings_section( 'push_syndicate_user_roles', esc_html__(' User Roles Configuration '), array( &$this, 'display_push_user_roles_description' ), 'push_syndicate_user_roles');
+        add_settings_field( 'user_role_selection', esc_html__(' select user roles '), array( &$this, 'display_user_roles_selection' ), 'push_syndicate_user_roles', 'push_syndicate_user_roles' );
+
+        add_settings_section( 'delete_pushed_posts', esc_html__(' Delete Pushed Posts '), array( &$this, 'display_delete_pushed_posts_description' ), 'delete_pushed_posts');
+        add_settings_field( 'delete_post_check', esc_html__(' delete pushed posts '), array( &$this, 'display_delete_pushed_posts_selection' ), 'delete_pushed_posts', 'delete_pushed_posts' );
+
+        add_settings_section( 'api_token', esc_html__(' API Token Configuration '), array( &$this, 'display_apitoken_description' ), 'api_token');
+        add_settings_field( 'client_id', esc_html__(' Enter your client id '), array( &$this, 'display_client_id' ), 'api_token', 'api_token' );
+        add_settings_field( 'client_secret', esc_html__(' Enter your client secret '), array( &$this, 'display_client_secret' ), 'api_token', 'api_token' );
+
+        ?>
+    <div class="wrap" xmlns="http://www.w3.org/1999/html">
+
+        <?php screen_icon(); // @TODO custom screen icon ?>
+
+        <h2><?php esc_html_e( 'Push Syndicate Settings' ); ?></h2>
+
+        <form action="options.php" method="post">
+
+            <?php settings_fields( 'push_syndicate_settings' ); ?>
+
+            <?php do_settings_sections( 'push_syndicate_post_types' ); ?>
+
+            <?php do_settings_sections( 'push_syndicate_user_roles' ); ?>
+
+            <?php do_settings_sections( 'delete_pushed_posts' ); ?>
+
+            <?php do_settings_sections( 'api_token' ); ?>
+
+            <?php submit_button(); ?>
+
+        </form>
+
+        <?php $this->get_api_token() ?>
+
+    </div>
+    <?php
+
+    }
+
+    public function display_push_post_types_description() {
+        echo '<p>Select the post types to add support for pushing content</p>';
+    }
+
+    public function display_post_types_selection() {
+
+        // @TODO filter suitably
+        $post_types = get_post_types( array( 'public' => true ) );
+        $selected_post_types = !empty( $this->push_syndicate_settings[ 'selected_post_types' ] ) ? $this->push_syndicate_settings[ 'selected_post_types' ] : array();
+
+        echo '<ul>';
+
+        foreach( $post_types as $post_type  ) {
+
+            ?>
+        <li>
+            <label>
+                <input type="checkbox" name="push_syndicate_settings[selected_post_types][]" value="<?php echo $post_type; ?>" <?php echo $this->checked_array( $post_type, $selected_post_types ); ?>/>
+                <?php echo $post_type; ?>
+            </label>
+        </li>
+        <?php
+
+        }
+
+        echo '</ul>';
+
+    }
+
+    public function display_push_user_roles_description() {
+        echo '<p>Select the user roles to enable for pushing content</p>';
+    }
+
+    public function display_user_roles_selection() {
+
+        $user_roles = $this->get_user_roles();
+        $selected_user_roles = !empty( $this->push_syndicate_settings[ 'selected_user_roles' ] ) ? $this->push_syndicate_settings[ 'selected_user_roles' ] : array();
+
+        echo '<ul>';
+
+        foreach( $user_roles as $user_role ) {
+
+            ?>
+        <li>
+            <label>
+                <input type="checkbox" name="push_syndicate_settings[selected_user_roles][]" value="<?php echo $user_role; ?>" <?php echo $this->checked_array( $user_role, $selected_user_roles ); ?>/>
+                <?php echo $user_role; ?>
+            </label>
+        </li>
+        <?php
+
+        }
+
+        echo '</ul>';
+
+    }
+
+    public function get_user_roles() {
+        global $wp_roles;
+
+        if ( ! isset( $wp_roles ) )
+            $wp_roles = new WP_Roles();
+
+        return $wp_roles->get_names();
+    }
+
+    public function display_delete_pushed_posts_description() {
+        echo '<p>Tick the box to delete all the pushed posts when the master post is deleted</p>';
+    }
+
+    public function display_delete_pushed_posts_selection() {
+
+        // default value is off
+        $delete_pushed_posts =  isset( $this->push_syndicate_settings[ 'delete_pushed_posts' ] ) ? $this->push_syndicate_settings[ 'delete_pushed_posts' ] : 'off' ;
+        echo '<input type="checkbox" name="push_syndicate_settings[delete_pushed_posts]" value="on" '; echo checked( $delete_pushed_posts, 'on' ) . ' />';
+
+    }
+
+    public function  display_apitoken_description() {
+        // @TODO add client type
+        ?>
+    <p>To push content to WordPress.com you must <a href="https://developer.wordpress.com/apps/new/">create a new application</a></p>
+    <p>Enter the Redirect URI as follows</p>
+    <p><b><?php echo esc_html(menu_page_url( 'push-syndicate-settings', false ))?></b></p>
+    <?php
+
+    }
+
+    public function display_client_id() {
+        echo '<input type="text" size=100 name="push_syndicate_settings[client_id]" value="' . esc_html( $this->push_syndicate_settings['client_id'] ) . '"/>';
+    }
+
+    public function display_client_secret() {
+        echo '<input type="text" size=100 name="push_syndicate_settings[client_secret]" value="' . esc_html( $this->push_syndicate_settings['client_secret'] ) . '"/>';
+    }
+
+    public function get_api_token() {
+
+        $redirect_uri = menu_page_url( 'push-syndicate-settings', false );
+        $authorization_endpoint = 'https://public-api.wordpress.com/oauth2/authorize?client_id=' . $this->push_syndicate_settings['client_id'] . '&redirect_uri=' .  $redirect_uri . '&response_type=code';
+
+        echo '<h3>Authorization</h3>';
+
+        // if code is not found return
+        if( empty( $_GET['code'] ) || !empty( $_GET[ 'settings-updated' ] ) ) {
+
+            ?>
+        <p>Click the authorize button to generate api token</p>
+        <input type=button class="button-primary" onClick="parent.location='<?php echo esc_html($authorization_endpoint); ?>'" value=" Authorize  ">
+        <?php
+
+            return;
+        }
+
+        $response = wp_remote_post( 'https://public-api.wordpress.com/oauth2/token', array(
+            'method' => 'POST',
+            'sslverify' => false,
+            'body' => array (
+                'client_id' => $this->push_syndicate_settings['client_id'],
+                'redirect_uri' => $redirect_uri,
+                'client_secret' => $this->push_syndicate_settings['client_secret'],
+                'code' => $_GET['code'],
+                'grant_type' => 'authorization_code'
+            ),
+        ) );
+
+        $result = json_decode( $response['body'] );
+
+        if( !empty( $result->error ) ) {
+
+            ?>
+        <p>Error retrieving API token <?php echo $result->error_description; ?> Please authorize again</p>
+        <input type=button class="button-primary" onClick="parent.location='<?php echo $authorization_endpoint; ?>'" value=" Authorize  ">
+        <?php
+
+            return;
+        }
+
+
+        ?>
+    <table class="form-table">
+        <tbody>
+        <tr valign="top">
+            <th scope="row">Access token</th>
+            <td><?php echo esc_html( $result->access_token ); ?></td>
+        </tr>
+        <tr valign="top">
+            <th scope="row">Blog ID</th>
+            <td><?php echo esc_html( $result->blog_id ); ?></td>
+        </tr>
+        <tr valign="top">
+            <th scope="row">Blog URL</th>
+            <td><?php echo esc_html( $result->blog_url ); ?></td>
+        </tr>
+        </tbody>
+    </table>
+    <p>Enter the above details in relevant fields when registering a <a href="http://wordpress.com" target="_blank">WordPress.com</a> site</p>
+    <?php
+
+    }
+
+    public function display_site_options() {
+
+        update_option( 'syn_selected_siteoptions', $_POST['syn_selected_siteoptions'] );
+        update_option( 'syn_selected_sitegroups', $_POST['syn_selected_sitegroups'] );
+
+        $this->schedule_syndicate_options_cron();
+
+        ?>
+    <div class="wrap" xmlns="http://www.w3.org/1999/html">
+
+        <?php screen_icon(); // @TODO custom screen icon ?>
+
+        <h2><?php esc_html_e( 'Push Syndicate Site Options' ); ?></h2>
+
+        <form action="" method="post">
+
+            <?php $this->display_sitegroups_selection(); ?>
+
+            <?php $this->display_site_options_selections(); ?>
+
+            <?php submit_button( '  Push Options  ' ); ?>
+
+        </form>
+
+    </div>
+    <?php
+
+    }
+
+    public function display_sitegroups_selection() {
+
+        echo '<h3>Select Sitegroups</h3>';
+
+        $selected_sitegroups = get_option( 'syn_selected_sitegroups' );
+        $selected_sitegroups = !empty( $selected_sitegroups ) ? $selected_sitegroups : array() ;
+
+        // get all sitegroups
+        $sitegroups = get_terms( 'syn_sitegroup', array(
+            'fields' => 'all',
+            'hide_empty' => false,
+            'orderby' => 'name'
+        ) );
+
+        foreach( $sitegroups as $sitegroup ) {
+
+            ?>
+        <p>
+            <label>
+                <input type="checkbox" name="syn_selected_sitegroups[]" value="<?php echo esc_html( $sitegroup->slug ); ?>" <?php $this->checked_array( $sitegroup->slug, $selected_sitegroups ) ?> />
+                <?php echo esc_html( $sitegroup->name ); ?>
+            </label>
+            <?php echo esc_html( $sitegroup->description ); ?>
+        </p>
+        <?php
+
+        }
+
+
+    }
+
+    public function display_site_options_selections() {
+
+        echo '<h3>Select Site Options</h3>';
+
+        $selected_siteoptions = get_option( 'syn_selected_siteoptions' );
+        $selected_siteoptions = !empty( $selected_siteoptions ) ? $selected_siteoptions : array() ;
+
+        $site_options = wp_load_alloptions();
+
+        echo '<table>';
+        echo '<tbody>';
+
+        $i = 0;
+
+        foreach( $site_options as $key => $value ) {
+
+            if( $key[0] == '_' )
+                continue;
+
+            if ( $i == 6 ) {
+                echo '<tr>';
+            }
+
+            ?>
+        <td>
+            <label>
+                <input type="checkbox" name="syn_selected_siteoptions[]" value="<?php echo esc_html( $key ); ?>" <?php $this->checked_array( $key, $selected_siteoptions ) ?> />
+                <?php echo esc_html( $key ); ?>
+            </label>
+        </td>
+        <?php
+
+            $i++;
+
+            if ( $i == 6 ) {
+                echo '<tr>';
+                $i = 0;
+            }
+
+        }
+
+        echo '</tbody>';
+        echo '</table>';
+
+    }
+
+    /*******  SYNCING OPTIONS  *******/
+    public function schedule_syndicate_options_cron() {
+
+        // @TODO Refractor this with new custom capability
+        if ( !current_user_can( 'manage_options' ) )
+            return;
+
+        $selected_sitegroups = get_option( 'syn_selected_sitegroups' );
+
+        $sites = array();
+        foreach( $selected_sitegroups as $selected_sitegroup ) {
+            $sites = array_merge( $sites, $this->get_sites_by_sitegroup( $selected_sitegroup ) );
+        }
+
+        wp_schedule_single_event(
+            time() - 1,
+            'syn_syndicate_options',
+            array( $sites )
+        );
+
+    }
+
+    public function syndicate_options( $sites ) {
+
+        require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
+
+        $selected_siteoptions = array_intersect_key( wp_load_alloptions(), array_combine( get_option( 'syn_selected_siteoptions' ), get_option( 'syn_selected_siteoptions' ) ) );
+
+        // Holds the error sites with the error message
+        $error_sites = array();
+
+        foreach( $sites as $site ) {
+
+            $site_enabled = get_post_meta( $site->ID, 'syn_site_enabled', true);
+            if( $site_enabled != 'on' )
+                continue;
+
+            $transport_type = get_post_meta( $site->ID, 'syn_transport_type', true);
+            $client = wp_client_factory::get_client( $transport_type  ,$site->ID );
+            $result = $client->set_options( $selected_siteoptions, $site->ID );
+            if( !$result ) {
+                $error_sites[] = array(
+
+                );
+            }
+        }
+
+        update_option( 'syn_options_error_sites', $error_sites );
+
+    }
+
+    /*******   SITE METABOXES   *********/
+    public function site_metaboxes() {
+        add_meta_box('sitediv', __(' Site Settings '), array( &$this, 'add_site_settings_metabox' ), 'syn_site', 'normal', 'high');
+        remove_meta_box('submitdiv', 'syn_site', 'side');
+    }
+
+    public function add_site_settings_metabox( $post ) {
+
+        global $post;
+
+        $transport_type = get_post_meta( $post->ID, 'syn_transport_type', true);
+        $site_enabled = get_post_meta( $post->ID, 'syn_site_enabled', true);
+
+        // default values
+        $transport_type = !empty( $transport_type ) ? $transport_type : 'wp_xmlrpc' ;
+        $site_enabled   = !empty( $site_enabled ) ? $site_enabled : 'off' ;
+
+        // nonce for verification when saving
+        wp_nonce_field( plugin_basename( __FILE__ ), 'site_settings_noncename' );
+
+        $this->display_transports( $transport_type );
+
+        try {
+            $class = $transport_type . '_client';
+            wp_client_factory::display_client_settings( $post, $class );
+        } catch(Exception $e) {
+            echo $e;
+        }
+
+        ?>
+    <p>
+        <input type="checkbox" name="site_enabled" <?php echo checked( $site_enabled, 'on' ); ?>/>
+        <label> Enable </label>
+    </p>
+    <p class="submit">
+        <input type="submit" name="addsite" id="addsite" class="button-primary" value="  Add Site  "/>
+    </p>
+    <div class="clear"></div>
+    <?php
+
+    }
+
+    public function display_transports( $transport_type ) {
+
+        echo '<p>Select a transport type</p>';
+        echo '<form action="">';
+        echo '<select name="transport_type" onchange="this.form.submit()">';
+
+        foreach( $this->push_syndicate_tranports as $key => $value ) {
+            echo '<option value="' . esc_html( $key ) . '"' . selected( $key, $transport_type ) . '>' . esc_html( $value['name'] ) . '</option>';
+        }
+
+        echo '</select>';
+        echo '</form>';
+
+    }
+
+    public function save_site_settings() {
+
+        global $post;
+
+        // autosave verification
+        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
+            return;
+
+        // if our nonce isn't there, or we can't verify it return
+        if( !isset( $_POST['site_settings_noncename'] ) || !wp_verify_nonce( $_POST['site_settings_noncename'], plugin_basename( __FILE__ ) ) )
+            return;
+
+        // @TODO Refractor this with new custom capability
+        if ( !current_user_can( 'manage_options' ) )
+            return;
+
+        update_post_meta( $post->ID, 'syn_transport_type', $_POST['transport_type'] );
+
+        $site_enabled = isset( $_POST['site_enabled'] ) ? 'on' : 'off';
+        $class = $_POST['transport_type'] . '_client';
+
+        try {
+            $save = wp_client_factory::save_client_settings( $post->ID, $class );
+            if( !$save )
+                return;
+            $client = wp_client_factory::get_client( $_POST['transport_type'], $post->ID );
+
+            if( $client->test_connection()  ) {
+                add_filter('redirect_post_location', create_function( '$location', 'return add_query_arg("message", 251, $location);' ) );
+            } else {
+                $site_enabled = 'off';
+            }
+
+        } catch( Exception $e ) {
+            add_filter('redirect_post_location', create_function( '$location', 'return add_query_arg("message", 250, $location);' ) );
+        }
+
+        update_post_meta( $post->ID, 'syn_site_enabled', $site_enabled );
+
+    }
+
+    public function push_syndicate_admin_messages( $messages ) {
+
+        // general error messages
+        $messages['syn_site'][250] = __( 'Transport class not found!' );
+        $messages['syn_site'][251] = __( 'Connection Successful!' );
+
+        // xmlrpc error messages.
+        $messages['syn_site'][301] = __( 'Invalid URL.' );
+        $messages['syn_site'][302] = __( 'You do not have sufficient capability to perform this action.' );
+        $messages['syn_site'][303] = __( 'Bad login/pass combination.' );
+        $messages['syn_site'][304] = __( 'XML-RPC services are disabled on this site.' );
+        $messages['syn_site'][305] = __( 'Transport error. Invalid endpoint' );
+        $messages['syn_site'][306] = __( 'Something went wrong when connecting to the site.' );
+
+        // WordPress.com REST error messages
+        $messages['site'][301] = __( 'Invalid URL' );
+
+        return $messages;
+    }
+
+    /******* SYNDICATION METABOXES   *********/
+    public function add_post_metaboxes() {
+
+        // return if no post types supports push syndication
+        if( empty( $this->push_syndicate_settings[ 'selected_post_types' ] ) )
+            return;
+
+        if ( !current_user_can( 'manage_options' ) )
+            return;
+
+        $selected_post_types = $this->push_syndicate_settings[ 'selected_post_types' ];
+        foreach( $selected_post_types as $selected_post_type ) {
+            add_meta_box( 'syndicatediv', __( ' Syndicate ' ), array( &$this, 'add_syndicate_metabox' ), $selected_post_type, 'side', 'high' );
+            //add_meta_box( 'syndicationstatusdiv', __( ' Syndication Status ' ), array( &$this, 'add_syndication_status_metabox' ), $selected_post_type, 'normal', 'high' );
+        }
+
+    }
+
+    public function add_syndicate_metabox( ) {
+
+        global $post;
+
+        // @TODO Refractor this with new custom capability
+        if ( !current_user_can( 'manage_options' ) )
+            return;
+
+        // nonce for verification when saving
+        wp_nonce_field( plugin_basename( __FILE__ ), 'syndicate_noncename' );
+
+        // get all sitegroups
+        $sitegroups = get_terms( 'syn_sitegroup', array(
+            'fields' => 'all',
+            'hide_empty' => false,
+            'orderby' => 'name'
+        ) );
+
+        // if there are no sitegroups defined retrun
+        if( empty( $sitegroups ) ) {
+            echo '<p>No sitegroups defined yet. You must group your sites into sitegroups to syndicate content</p>';
+            echo '<p><a href="' . esc_url( get_admin_url() . 'edit-tags.php?taxonomy=sitegroups&post_type=site' ) . '" target="_blank" >Create new</a></p>';
+            return;
+        }
+
+        $selected_sitegroups = get_post_meta( $post->ID, '_syn_selected_sitegroups', true );
+        $selected_sitegroups = !empty( $selected_sitegroups ) ? $selected_sitegroups : array() ;
+
+        echo '<ul>';
+
+        foreach( $sitegroups as $sitegroup  ) {
+
+            ?>
+        <li>
+            <label>
+                <input type="checkbox" name="selected_sitegroups[]" value="<?php echo esc_html( $sitegroup->slug ); ?>" <?php $this->checked_array( $sitegroup->slug, $selected_sitegroups ) ?> />
+                <?php echo esc_html( $sitegroup->name ); ?>
+            </label>
+            <p> <?php echo esc_html( $sitegroup->description ); ?> </p>
+        </li>
+        <?php
+
+        }
+
+        echo '</ul>';
+
+    }
+
+    public function checked_array( $sitegroup, $selected_sitegroups ) {
+        if( !empty( $selected_sitegroups ) ) {
+            if( in_array( $sitegroup, $selected_sitegroups ) ) {
+                echo 'checked="checked"';
+            }
+        }
+    }
+
+    public function save_syndicate_settings() {
+
+        global $post;
+
+        // autosave verification
+        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
+            return;
+
+        // if our nonce isn't there, or we can't verify it return
+        if( !isset( $_POST['syndicate_noncename'] ) || !wp_verify_nonce( $_POST['syndicate_noncename'], plugin_basename( __FILE__ ) ) )
+            return;
+
+        // @TODO Refractor this with new custom capability
+        if ( !current_user_can( 'manage_options' ) )
+            return;
+
+        $selected_sitegroups = !empty( $_POST['selected_sitegroups'] ) ? $_POST['selected_sitegroups'] : '' ;
+        update_post_meta( $post->ID, '_syn_selected_sitegroups', $selected_sitegroups );
+
+    }
+
+    public function add_syndication_status_metabox() {
+        // @TODO retrieve syndication status and display
+    }
+
+    // @TODO scheduling happens before saving?
+    /*******    SYNCING CONTENT   *******/
+    public function schedule_syndicate_content_cron() {
+
+        global $post;
+
+        // autosave verification
+        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
+            return;
+
+        // if our nonce isn't there, or we can't verify it return
+        if( !isset( $_POST['syndicate_noncename'] ) || !wp_verify_nonce( $_POST['syndicate_noncename'], plugin_basename( __FILE__ ) ) )
+            return;
+
+        // @TODO Refractor this with new custom capability
+        if ( !current_user_can( 'manage_options' ) )
+            return;
+
+        $sites = $this->get_sites_by_post_ID( $post->ID );
+
+        wp_schedule_single_event(
+            time() - 1,
+            'syn_syndicate_content',
+            array( $sites )
+        );
+
+    }
+
+    // cron job function to syndicate content
+    public function syndicate_content( $sites ) {
+
+        // if another process running on it return
+        if( get_transient( 'syn_syndicate_lock' ) == 'locked' )
+            return
+
+                // set value as locked, valid for 5 mins
+                set_transient( 'syn_syndicate_lock', 'locked', 60*5 );
+
+        /** start of critical section **/
+
+        require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
+
+        $post_ID = $sites[ 'post_ID' ];
+
+        // an array containing states of sites
+        $slave_post_states = get_post_meta( $post_ID, '_syn_slave_post_states', true );
+        $slave_post_states = !empty( $slave_post_states ) ? $slave_post_states : array() ;
+
+        if( !empty( $sites[ 'selected_sites' ] ) ) {
+
+            foreach( $sites[ 'selected_sites' ] as $site ) {
+
+                $transport_type = get_post_meta( $site->ID, 'syn_transport_type', true);
+                $client = wp_client_factory::get_client( $transport_type  ,$site->ID );
+                $info = $this->get_site_info( $site->ID, $slave_post_states, $client );
+
+                if( $info['state'] == 'new' || $info['state'] == 'new-error' ) { // states 'new' and 'new-error'
+                    $result = $client->new_post( $post_ID );
+                    $this->validate_result_new_post( $result, $slave_post_states, $site->ID, $client );
+                } else { // states 'success', 'edit-error' and 'remove-error'
+                    $result = $client->edit_post( $post_ID, $info['ext_ID'] );
+                    $this->validate_result_edit_post( $result, $info, $slave_post_states, $site->ID, $client );
+                }
+
+            }
+
+        }
+
+        if( !empty( $sites[ 'removed_sites' ]) ) {
+
+            foreach( $sites[ 'removed_sites' ] as $site ) {
+
+                $transport_type = get_post_meta( $site->ID, 'syn_transport_type', true);
+                $client = wp_client_factory::get_client( $transport_type  ,$site->ID );
+                $info = $this->get_site_info( $site->ID, $slave_post_states, $client );
+
+                // if the post is not pushed we do not need to delete them
+                if( $info['state'] == 'success' || $info['state'] == 'edit-error' || $info['state'] == 'remove-error' ) {
+
+                    $result = $client->delete_post( $info['ext_ID'] );
+                    if( !$result ) {
+                        $slave_post_states[ 'remove-error' ][ $site->ID ] = array(
+                            'error_code'    => $client->get_error_code(),
+                            'error_message' => $client->get_error_message()
+                        );
+                    }
+
+                }
+
+            }
+
+        }
+
+        update_post_meta( $post_ID, '_syn_slave_post_states', $slave_post_states );
+
+        /** end of critical section **/
+
+        // release the lock.
+        delete_transient( 'syn_syndicate_lock' );
+
+    }
+
+    public function get_sites_by_post_ID( $post_ID ) {
+
+        $selected_sitegroups = get_post_meta( $post_ID, '_syn_selected_sitegroups', true );
+        $selected_sitegroups = !empty( $selected_sitegroups ) ? $selected_sitegroups : array() ;
+
+        $old_sitegroups = get_post_meta( $post_ID, '_syn_old_sitegroups', true );
+        $old_sitegroups = !empty( $old_sitegroups ) ? $old_sitegroups : array() ;
+
+        $removed_sitegroups = array_diff( $old_sitegroups, $selected_sitegroups );
+
+        // initialization
+        $data = array(
+            'post_ID' => $post_ID,
+            'selected_sites' => array(),
+            'removed_sites' => array(),
+        );
+
+        if( !empty( $selected_sitegroups ) ) {
+
+            foreach( $selected_sitegroups as $selected_sitegroup ) {
+
+                // get all the sites in the sitegroup
+                $sites = $this->get_sites_by_sitegroup( $selected_sitegroup );
+                if( empty( $sites ) )
+                    continue;
+
+                foreach( $sites as $site ) {
+                    $site_enabled = get_post_meta( $site->ID, 'syn_site_enabled', true);
+                    if( $site_enabled == 'on' ) {
+                        $data[ 'selected_sites' ][] = $site;
+                    }
+                }
+
+            }
+
+        }
+
+        if( !empty( $removed_sitegroups ) ) {
+
+            foreach( $removed_sitegroups as $removed_sitegroup ) {
+
+                // get all the sites in the sitegroup
+                $sites = $this->get_sites_by_sitegroup( $removed_sitegroup );
+                if( empty( $sites ) )
+                    continue;
+
+                foreach( $sites as $site ) {
+                    $site_enabled = get_post_meta( $site->ID, 'syn_site_enabled', true);
+                    if( $site_enabled == 'on' ) {
+                        $data[ 'removed_sites' ][] = $site;
+                    }
+                }
+
+            }
+
+        }
+
+        update_post_meta( $post_ID, '_syn_old_sitegroups', $selected_sitegroups );
+
+        return $data;
+
+    }
+
+    // return an array of sites as objects based on sitegroup
+    public function get_sites_by_sitegroup( $sitegroup ) {
+
+        // @TODO if sitegroup is deleted?
+
+        $results = new WP_Query(array(
+            'post_type' => 'syn_site',
+            'posts_per_page' => -1, // retrieve all posts
+            'tax_query' => array(
+                array(
+                    'taxonomy' => 'syn_sitegroup',
+                    'field' => 'slug',
+                    'terms' => $sitegroup
+                )
+            )
+        ));
+
+        return $results->posts;
+
+    }
+
+    /**
+     * $site_states is an array containing state of the site
+     * with regard to the post the state. The states are
+     *  success - the post was pushed successfully.
+     *  new-error - error when creating the post.
+     *  edit-error - error when editing the post.
+     *  remove-error - error when removing the post in a slave site, when the sitegroup is unselected
+     *  new - if the state is not found or the post is deleted in the slave site.
+     */
+    public function get_site_info( $site_ID, &$slave_post_states, $client ) {
+
+        if( empty( $slave_post_states ) )
+            return array( 'state' => 'new' );
+
+        foreach( $slave_post_states as $state => $sites  ) {
+            if(   array_key_exists( $site_ID, $sites )   &&   !empty( $sites[ $site_ID ]['ext_ID'] )   ) {
+                if( $client->is_post_exists( $sites[ $site_ID ]['ext_ID'] ) ) {
+                    $info = array( 'state' => $state, 'ext_ID' => $sites[ $site_ID ]['ext_ID'] );
+                    unset( $slave_post_states[ $state ] [$site_ID] );
+                    return $info;
+                } else {
+                    return array( 'state' => 'new' );
+                }
+            }
+        }
+
+        return array( 'state' => 'new' );
+
+    }
+
+    /**
+     * if the result is false state transitions
+     * new          -> new-error
+     * new-error    -> new-error
+     * remove-error -> new-error
+     */
+    public function validate_result_new_post( $result, &$slave_post_states, $site_ID, $client ) {
+
+        if( $result ) {
+            $slave_post_states[ 'success' ][ $site_ID ] = array(
+                'ext_ID'        => (int)$client->get_response()
+            );
+        } else {
+            $slave_post_states[ 'new-error' ][ $site_ID ] = array(
+                'error_code'    => $client->get_error_code(),
+                'error_message' => $client->get_error_message()
+            );
+        }
+
+    }
+
+    /**
+     * if the result is false state transitions
+     * edit-error   -> edit-error
+     * success      -> edit-error
+     */
+    public function validate_result_edit_post( $result, $info, &$slave_post_states, $site_ID, $client ) {
+
+        if( $result ) {
+            $slave_post_states[ 'success' ][ $site_ID ] = array(
+                'ext_ID'       => $info[ 'ext_ID' ]
+            );
+        } else {
+            $slave_post_states[ 'edit-error' ][ $site_ID ] = array(
+                'ext_ID'        => $info[ 'ext_ID' ],
+                'error_code'    => $client->get_error_code(),
+                'error_message' => $client->get_error_message()
+            );
+        }
+
+    }
+
+    /*******  DELETING CONTENT   *******/
+    public function delete_slave_posts( $post_ID ) {
+
+        // if slave post deletion is not enabled return
+        $delete_pushed_posts =  !empty( $this->push_syndicate_settings[ 'delete_pushed_posts' ] ) ? $this->push_syndicate_settings[ 'delete_pushed_posts' ] : 'off' ;
+        if( $delete_pushed_posts != 'on' )
+            return;
+
+        wp_schedule_single_event(
+            time() - 1,
+            'syn_delete_content',
+            array( $post_ID )
+        );
+
+    }
+
+    public function delete_content( $post_ID ) {
+
+        require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
+
+        $delete_error_sites = get_option( 'syn_delete_error_sites' );
+        $delete_error_sites = !empty( $delete_error_sites ) ? $delete_error_sites : array() ;
+        $slave_posts = $this->get_slave_posts( $post_ID );
+
+        if( empty( $slave_posts ) )
+            return;
+
+        foreach( $slave_posts as $site_ID => $ext_ID ) {
+
+            $site_enabled = get_post_meta( $site_ID, 'syn_site_enabled', true);
+
+            // check whether the site is enabled
+            if( $site_enabled == 'on' ) {
+
+                $transport_type = get_post_meta( $site_ID, 'syn_transport_type', true);
+                $client = wp_client_factory::get_client( $transport_type , $site_ID );
+
+                if( $client->is_post_exists( $ext_ID ) ) {
+
+                    $result = $client->delete_post( $ext_ID );
+                    if( !$result ) {
+                        $delete_error_sites[ $site_ID ] = array( $ext_ID );
+                    }
+
+                }
+
+            }
+
+        }
+
+        update_option( 'syn_delete_error_sites', $delete_error_sites );
+        // all post metadata will be automatically deleted including slave_post_states
+
+    }
+
+    // get the slave posts as $site_ID => $ext_ID
+    public function get_slave_posts( $post_ID ) {
+
+        // array containing states of sites
+        $slave_post_states = get_post_meta( $post_ID, '_syn_slave_post_states', true );
+
+        // array containing slave posts as $site_ID => $ext_ID
+        $slave_posts = array();
+
+        foreach( (array)$slave_post_states as $state ) {
+            foreach( $state as $site_ID => $info ) {
+                if( !empty( $info[ 'ext_ID' ] ) ) {
+                    $slave_posts[ $site_ID ] = $info[ 'ext_ID' ];
+                }
+            }
+        }
+
+        return $slave_posts;
+
+    }
+
+}
\ No newline at end of file
diff --git a/push-syndication-server.php b/push-syndication-server.php
index 308ba70cf40a3a929f006e88ace0f208222b196b..2255ee7232fe10718e48b8bec9ab8a140c4510af 100644
--- a/push-syndication-server.php
+++ b/push-syndication-server.php
@@ -12,1090 +12,6 @@ License:      GPLv2 or later
 
 **************************************************************************/
 
-// @TODO define a new capability to push syndicate
-// @TODO check add add_settings_field args
-// @TODO add help using contextual_help
-// @TODO mark helper functions as private?
-// @TODO check sites are publicly queryable
-// @TODO add options to retry delete_error_sites
-
-require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
-
-class Push_Syndication_Server {
-
-    private $push_syndicate_settings;
-	private $push_syndicate_tranports;
-
-    function __construct() {
-
-		// get plugin settings
-		$this->push_syndicate_settings = get_option( 'push_syndicate_settings' );
-
-		// initialization
-		add_action( 'init', array( &$this, 'init' ) );
-		add_action( 'admin_init', array( &$this, 'admin_init' ) );
-
-		// plugin settings submenus
-		add_action( 'admin_menu', array( &$this, 'register_syndicate_settings' ) );
-
-		// defining sites
-		add_action( 'save_post', array( &$this, 'save_site_settings' ) );
-
-		// loading necessary styles and scripts
-		add_action( 'admin_enqueue_scripts', array( &$this, 'load_scripts_and_styles' ) );
-
-		// filter admin notices in custom post types
-		add_filter( 'post_updated_messages', array( &$this, 'push_syndicate_admin_messages' ) );
-
-		// syndicating content
-		add_action( 'add_meta_boxes', array( &$this, 'add_post_metaboxes' ) );
-		add_action( 'save_post', array( &$this, 'save_syndicate_settings' ) );
-		add_action( 'wp_trash_post', array( &$this, 'delete_slave_posts' ) );
-
-		// firing a cron job
-		add_action( 'transition_post_status', array(&$this, 'schedule_syndicate_content_cron') );
-
-		// cron hooks
-		add_action( 'syn_syndicate_content', array(&$this, 'syndicate_content') );
-		add_action( 'syn_delete_content', array(&$this, 'delete_content') );
-		add_action( 'syn_syndicate_options', array(&$this, 'syndicate_options') );
-
-    }
-
-    public function init() {
-
-        register_post_type(
-            'syn_site',
-            array(
-                'labels' => array(
-                    'name'              => __( 'Sites' ),
-                    'singular_name'     => __( 'Site' ),
-                    'add_new'           => __( 'Add Site' ),
-                    'add_new_item'      => __( 'Add New Site' ),
-                    'edit_item'         => __( 'Edit Site' ),
-                    'new_item'          => __( 'New Site' ),
-                    'view_item'         => __( 'View Site' ),
-                    'search_items'      => __( 'Search Sites' ),
-                ),
-                'description'           => __( 'Sites in the netowrk' ),
-                'public'                => false,
-                'show_ui'               => true,
-                'publicly_queryable'    => false,
-                'exclude_from_search'   => false,
-                'menu_position'         => 80,
-                // @TODO we need a menu icon here
-                'hierarchical'          => false, // @TODO check this
-                'query_var'             => true,
-                // @TODO match capabilities with custom capabilities
-                'supports'              => array( 'title' ),
-                'can_export'            => true,
-                'register_meta_box_cb'  => array( &$this, 'site_metaboxes' ),
-            )
-        );
-
-        register_taxonomy(
-            'syn_sitegroup',
-            array( 'syn_site' ),
-            array(
-                'labels' => array(
-                    'name'              => __( 'Site Groups' ),
-                    'singular_name'     => __( 'Site Group' ),
-                    'search_items'      => __( 'Search Site Groups' ),
-                    'popular_items'     => __( 'Popular Site Groups' ),
-                    'all_items'         => __( 'All Site Groups' ),
-                    'parent_item'       => __( 'Parent Site Group' ),
-                    'parent_item_colon' => __( 'Parent Site Group' ),
-                    'edit_item'         => __( 'Edit Site Group' ),
-                    'update_item'       => __( 'Update Site Group' ),
-                    'add_new_item'      => __( 'Add New Site Group' ),
-                    'new_item_name'     => __( 'New Site Group Name' ),
-
-                ),
-                'public'                => false,
-                'show_ui'               => true,
-                'show_tagcloud'         => false,
-                'show_in_nav_menus'     => false,
-                'hierarchical'          => true,
-                // @TODO match capabilities with custom capabilities
-                'rewrite'               => false,
-            )
-        );
-
-
-    }
-
-    public function admin_init() {
-
-	    // @TODO define more parameters
-        $this->push_syndicate_tranports = array(
-	        'wp_xmlrpc'    => array(
-		        'name'  => 'WordPress XMLRPC',
-		        'path'  => ''
-	        ),
-	        'wp_rest'      => array(
-				'name'  => 'WordPress.com REST',
-		        'path'  => ''
-	        ),
-        );
-
-	    $this->push_syndicate_tranports = apply_filters( 'push_syndicate_transports', $this->push_syndicate_tranports );
-
-	    // register styles and scripts
-	    wp_register_style( 'syn_sites', plugins_url( 'css/sites.css', __FILE__ ) );
-
-        register_setting( 'push_syndicate_settings', 'push_syndicate_settings', array( &$this, 'push_syndicate_settings_validate' ) );
-
-	    // if no post types are selected set post by default
-	    if( empty( $this->push_syndicate_settings['selected_post_types'] )  ) {
-			$this->push_syndicate_settings['selected_post_types'] = array( 'post' );
-		    update_option( 'push_syndicate_settings', $this->push_syndicate_settings );
-	    }
-
-    }
-
-	/*******     STYLES AND SCRIPTS   ********/
-	public function load_scripts_and_styles( $hook ) {
-
-		global $typenow;
-		if( $hook == 'edit.php' && $typenow == 'syn_site') {
-			wp_enqueue_style( 'syn_sites' );
-		}
-
-	}
-
-	/*******     PLUGIN SETTINGS       *******/
-	public function push_syndicate_settings_validate( $raw_settings ) {
-
-		$settings = array();
-		$settings['client_id'] = sanitize_text_field( $raw_settings['client_id'] );
-		$settings['client_secret'] = sanitize_text_field( $raw_settings['client_secret'] );
-		$settings['selected_post_types'] = $raw_settings['selected_post_types'];
-		$settings['delete_pushed_posts'] = $raw_settings['delete_pushed_posts'];
-
-		return $raw_settings;
-
-	}
-
-	public function register_syndicate_settings() {
-		add_submenu_page( 'options-general.php', __( 'Push Syndicate Settings'), __( 'Push Syndicate Settings' ), 'manage_options', 'push-syndicate-settings', array( &$this, 'display_syndicate_settings' ) );
-		add_submenu_page( 'edit.php?post_type=syn_site', __( 'Site Options'), __( 'Site Options' ), 'manage_options', 'push-syndicate-site-options', array( &$this, 'display_site_options' ) );
-	}
-
-	public function display_syndicate_settings() {
-
-		add_settings_section( 'push_syndicate_post_types', esc_html__(' Post Type Configuration '), array( &$this, 'display_push_post_types_description' ), 'push_syndicate_post_types');
-		add_settings_field( 'post_type_selection', esc_html__(' select post types '), array( &$this, 'display_post_types_selection' ), 'push_syndicate_post_types', 'push_syndicate_post_types' );
-
-		add_settings_section( 'push_syndicate_user_roles', esc_html__(' User Roles Configuration '), array( &$this, 'display_push_user_roles_description' ), 'push_syndicate_user_roles');
-		add_settings_field( 'user_role_selection', esc_html__(' select user roles '), array( &$this, 'display_user_roles_selection' ), 'push_syndicate_user_roles', 'push_syndicate_user_roles' );
-
-		add_settings_section( 'delete_pushed_posts', esc_html__(' Delete Pushed Posts '), array( &$this, 'display_delete_pushed_posts_description' ), 'delete_pushed_posts');
-		add_settings_field( 'delete_post_check', esc_html__(' delete pushed posts '), array( &$this, 'display_delete_pushed_posts_selection' ), 'delete_pushed_posts', 'delete_pushed_posts' );
-
-		add_settings_section( 'api_token', esc_html__(' API Token Configuration '), array( &$this, 'display_apitoken_description' ), 'api_token');
-		add_settings_field( 'client_id', esc_html__(' Enter your client id '), array( &$this, 'display_client_id' ), 'api_token', 'api_token' );
-		add_settings_field( 'client_secret', esc_html__(' Enter your client secret '), array( &$this, 'display_client_secret' ), 'api_token', 'api_token' );
-
-?>
-	<div class="wrap" xmlns="http://www.w3.org/1999/html">
-
-		<?php screen_icon(); // @TODO custom screen icon ?>
-
-		<h2><?php esc_html_e( 'Push Syndicate Settings' ); ?></h2>
-
-		<form action="options.php" method="post">
-
-			<?php settings_fields( 'push_syndicate_settings' ); ?>
-
-			<?php do_settings_sections( 'push_syndicate_post_types' ); ?>
-
-			<?php do_settings_sections( 'push_syndicate_user_roles' ); ?>
-
-			<?php do_settings_sections( 'delete_pushed_posts' ); ?>
-
-			<?php do_settings_sections( 'api_token' ); ?>
-
-			<?php submit_button(); ?>
-
-		</form>
-
-		<?php $this->get_api_token() ?>
-
-	</div>
-<?php
-
-	}
-
-	public function display_push_post_types_description() {
-		echo '<p>Select the post types to add support for pushing content</p>';
-	}
-
-	public function display_post_types_selection() {
-
-		// @TODO filter suitably
-		$post_types = get_post_types( array( 'public' => true ) );
-		$selected_post_types = !empty( $this->push_syndicate_settings[ 'selected_post_types' ] ) ? $this->push_syndicate_settings[ 'selected_post_types' ] : array();
-
-		echo '<ul>';
-
-		foreach( $post_types as $post_type  ) {
-
-?>
-		<li>
-			<label>
-				<input type="checkbox" name="push_syndicate_settings[selected_post_types][]" value="<?php echo $post_type; ?>" <?php echo $this->checked_array( $post_type, $selected_post_types ); ?>/>
-				<?php echo $post_type; ?>
-			</label>
-		</li>
-<?php
-
-		}
-
-		echo '</ul>';
-
-	}
-
-	public function display_push_user_roles_description() {
-		echo '<p>Select the user roles to enable for pushing content</p>';
-	}
-
-	public function display_user_roles_selection() {
-
-		$user_roles = $this->get_user_roles();
-		$selected_user_roles = !empty( $this->push_syndicate_settings[ 'selected_user_roles' ] ) ? $this->push_syndicate_settings[ 'selected_user_roles' ] : array();
-
-		echo '<ul>';
-
-		foreach( $user_roles as $user_role ) {
-
-?>
-		<li>
-			<label>
-				<input type="checkbox" name="push_syndicate_settings[selected_user_roles][]" value="<?php echo $user_role; ?>" <?php echo $this->checked_array( $user_role, $selected_user_roles ); ?>/>
-				<?php echo $user_role; ?>
-			</label>
-		</li>
-<?php
-
-		}
-
-		echo '</ul>';
-
-	}
-
-	public function get_user_roles() {
-		global $wp_roles;
-
-		if ( ! isset( $wp_roles ) )
-			$wp_roles = new WP_Roles();
-
-		return $wp_roles->get_names();
-	}
-
-	public function display_delete_pushed_posts_description() {
-		echo '<p>Tick the box to delete all the pushed posts when the master post is deleted</p>';
-	}
-
-	public function display_delete_pushed_posts_selection() {
-
-		// default value is off
-		$delete_pushed_posts =  isset( $this->push_syndicate_settings[ 'delete_pushed_posts' ] ) ? $this->push_syndicate_settings[ 'delete_pushed_posts' ] : 'off' ;
-		echo '<input type="checkbox" name="push_syndicate_settings[delete_pushed_posts]" value="on" '; echo checked( $delete_pushed_posts, 'on' ) . ' />';
-
-	}
-
-	public function  display_apitoken_description() {
-		// @TODO add client type
-?>
-		<p>To push content to WordPress.com you must <a href="https://developer.wordpress.com/apps/new/">create a new application</a></p>
-		<p>Enter the Redirect URI as follows</p>
-		<p><b><?php echo esc_html(menu_page_url( 'push-syndicate-settings', false ))?></b></p>
-<?php
-
-	}
-
-	public function display_client_id() {
-		echo '<input type="text" size=100 name="push_syndicate_settings[client_id]" value="' . esc_html( $this->push_syndicate_settings['client_id'] ) . '"/>';
-	}
-
-	public function display_client_secret() {
-		echo '<input type="text" size=100 name="push_syndicate_settings[client_secret]" value="' . esc_html( $this->push_syndicate_settings['client_secret'] ) . '"/>';
-	}
-
-	public function get_api_token() {
-
-		$redirect_uri = menu_page_url( 'push-syndicate-settings', false );
-		$authorization_endpoint = 'https://public-api.wordpress.com/oauth2/authorize?client_id=' . $this->push_syndicate_settings['client_id'] . '&redirect_uri=' .  $redirect_uri . '&response_type=code';
-
-		echo '<h3>Authorization</h3>';
-
-		// if code is not found return
-		if( empty( $_GET['code'] ) || !empty( $_GET[ 'settings-updated' ] ) ) {
-
-?>
-		<p>Click the authorize button to generate api token</p>
-		<input type=button class="button-primary" onClick="parent.location='<?php echo esc_html($authorization_endpoint); ?>'" value=" Authorize  ">
-<?php
-
-			return;
-		}
-
-		$response = wp_remote_post( 'https://public-api.wordpress.com/oauth2/token', array(
-			'method' => 'POST',
-			'sslverify' => false,
-			'body' => array (
-				'client_id' => $this->push_syndicate_settings['client_id'],
-				'redirect_uri' => $redirect_uri,
-				'client_secret' => $this->push_syndicate_settings['client_secret'],
-				'code' => $_GET['code'],
-				'grant_type' => 'authorization_code'
-			),
-		) );
-
-		$result = json_decode( $response['body'] );
-
-		if( !empty( $result->error ) ) {
-
-?>
-		<p>Error retrieving API token <?php echo $result->error_description; ?> Please authorize again</p>
-		<input type=button class="button-primary" onClick="parent.location='<?php echo $authorization_endpoint; ?>'" value=" Authorize  ">
-<?php
-
-			return;
-		}
-
-
-?>
-		<table class="form-table">
-			<tbody>
-			<tr valign="top">
-				<th scope="row">Access token</th>
-				<td><?php echo esc_html( $result->access_token ); ?></td>
-			</tr>
-			<tr valign="top">
-				<th scope="row">Blog ID</th>
-				<td><?php echo esc_html( $result->blog_id ); ?></td>
-			</tr>
-			<tr valign="top">
-				<th scope="row">Blog URL</th>
-				<td><?php echo esc_html( $result->blog_url ); ?></td>
-			</tr>
-			</tbody>
-		</table>
-		<p>Enter the above details in relevant fields when registering a <a href="http://wordpress.com" target="_blank">WordPress.com</a> site</p>
-<?php
-
-	}
-
-	public function display_site_options() {
-
-		update_option( 'syn_selected_siteoptions', $_POST['syn_selected_siteoptions'] );
-		update_option( 'syn_selected_sitegroups', $_POST['syn_selected_sitegroups'] );
-
-		$this->schedule_syndicate_options_cron();
-
-?>
-	<div class="wrap" xmlns="http://www.w3.org/1999/html">
-
-		<?php screen_icon(); // @TODO custom screen icon ?>
-
-		<h2><?php esc_html_e( 'Push Syndicate Site Options' ); ?></h2>
-
-		<form action="" method="post">
-
-			<?php $this->display_sitegroups_selection(); ?>
-
-			<?php $this->display_site_options_selections(); ?>
-
-			<?php submit_button( '  Push Options  ' ); ?>
-
-		</form>
-
-	</div>
-<?php
-
-	}
-
-	public function display_sitegroups_selection() {
-
-		echo '<h3>Select Sitegroups</h3>';
-
-		$selected_sitegroups = get_option( 'syn_selected_sitegroups' );
-		$selected_sitegroups = !empty( $selected_sitegroups ) ? $selected_sitegroups : array() ;
-
-		// get all sitegroups
-		$sitegroups = get_terms( 'syn_sitegroup', array(
-			'fields' => 'all',
-			'hide_empty' => false,
-			'orderby' => 'name'
-		) );
-
-		foreach( $sitegroups as $sitegroup ) {
-
-?>
-			<p>
-				<label>
-					<input type="checkbox" name="syn_selected_sitegroups[]" value="<?php echo esc_html( $sitegroup->slug ); ?>" <?php $this->checked_array( $sitegroup->slug, $selected_sitegroups ) ?> />
-					<?php echo esc_html( $sitegroup->name ); ?>
-				</label>
-				<?php echo esc_html( $sitegroup->description ); ?>
-			</p>
-<?php
-
-		}
-
-
-	}
-
-	public function display_site_options_selections() {
-
-		echo '<h3>Select Site Options</h3>';
-
-		$selected_siteoptions = get_option( 'syn_selected_siteoptions' );
-		$selected_siteoptions = !empty( $selected_siteoptions ) ? $selected_siteoptions : array() ;
-
-		$site_options = wp_load_alloptions();
-
-		echo '<table>';
-		echo '<tbody>';
-
-		$i = 0;
-
-		foreach( $site_options as $key => $value ) {
-
-			if( $key[0] == '_' )
-				continue;
-
-			if ( $i == 6 ) {
-				echo '<tr>';
-			}
-
-?>
-				<td>
-					<label>
-						<input type="checkbox" name="syn_selected_siteoptions[]" value="<?php echo esc_html( $key ); ?>" <?php $this->checked_array( $key, $selected_siteoptions ) ?> />
-						<?php echo esc_html( $key ); ?>
-					</label>
-				</td>
-<?php
-
-			$i++;
-
-			if ( $i == 6 ) {
-				echo '<tr>';
-				$i = 0;
-			}
-
-		}
-
-		echo '</tbody>';
-		echo '</table>';
-
-	}
-
-	/*******  SYNCING OPTIONS  *******/
-	public function schedule_syndicate_options_cron() {
-
-		// @TODO Refractor this with new custom capability
-		if ( !current_user_can( 'manage_options' ) )
-			return;
-
-		$selected_sitegroups = get_option( 'syn_selected_sitegroups' );
-
-		$sites = array();
-		foreach( $selected_sitegroups as $selected_sitegroup ) {
-			$sites = array_merge( $sites, $this->get_sites_by_sitegroup( $selected_sitegroup ) );
-		}
-
-		wp_schedule_single_event(
-			time() - 1,
-			'syn_syndicate_options',
-			array( $sites )
-		);
-
-	}
-
-	public function syndicate_options( $sites ) {
-
-		require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
-
-		$selected_siteoptions = array_intersect_key( wp_load_alloptions(), array_combine( get_option( 'syn_selected_siteoptions' ), get_option( 'syn_selected_siteoptions' ) ) );
-
-		// Holds the error sites with the error message
-		$error_sites = array();
-
-		foreach( $sites as $site ) {
-
-			$site_enabled = get_post_meta( $site->ID, 'syn_site_enabled', true);
-			if( $site_enabled != 'on' )
-				continue;
-
-			$transport_type = get_post_meta( $site->ID, 'syn_transport_type', true);
-			$client = wp_client_factory::get_client( $transport_type  ,$site->ID );
-			$result = $client->set_options( $selected_siteoptions, $site->ID );
-			if( !$result ) {
-				$error_sites[] = array(
-
-				);
-			}
-		}
-
-		update_option( 'syn_options_error_sites', $error_sites );
-
-	}
-
-	/*******   SITE METABOXES   *********/
-    public function site_metaboxes() {
-        add_meta_box('sitediv', __(' Site Settings '), array( &$this, 'add_site_settings_metabox' ), 'syn_site', 'normal', 'high');
-        remove_meta_box('submitdiv', 'syn_site', 'side');
-    }
-
-    public function add_site_settings_metabox( $post ) {
-
-	    global $post;
-
-        $transport_type = get_post_meta( $post->ID, 'syn_transport_type', true);
-	    $site_enabled = get_post_meta( $post->ID, 'syn_site_enabled', true);
-
-	    // default values
-	    $transport_type = !empty( $transport_type ) ? $transport_type : 'wp_xmlrpc' ;
-	    $site_enabled   = !empty( $site_enabled ) ? $site_enabled : 'off' ;
-
-	    // nonce for verification when saving
-	    wp_nonce_field( plugin_basename( __FILE__ ), 'site_settings_noncename' );
-
-	    $this->display_transports( $transport_type );
-
-	    try {
-		    $class = $transport_type . '_client';
-		    wp_client_factory::display_client_settings( $post, $class );
-	    } catch(Exception $e) {
-		    echo $e;
-	    }
-
-?>
-	    <p>
-		    <input type="checkbox" name="site_enabled" <?php echo checked( $site_enabled, 'on' ); ?>/>
-		    <label> Enable </label>
-	    </p>
-		<p class="submit">
-			<input type="submit" name="addsite" id="addsite" class="button-primary" value="  Add Site  "/>
-		</p>
-		<div class="clear"></div>
-<?php
-
-    }
-
-	public function display_transports( $transport_type ) {
-
-		echo '<p>Select a transport type</p>';
-		echo '<form action="">';
-		echo '<select name="transport_type" onchange="this.form.submit()">';
-
-		foreach( $this->push_syndicate_tranports as $key => $value ) {
-			echo '<option value="' . esc_html( $key ) . '"' . selected( $key, $transport_type ) . '>' . esc_html( $value['name'] ) . '</option>';
-		}
-
-		echo '</select>';
-		echo '</form>';
-
-	}
-
-    public function save_site_settings() {
-
-	    global $post;
-
-        // autosave verification
-        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
-            return;
-
-        // if our nonce isn't there, or we can't verify it return
-        if( !isset( $_POST['site_settings_noncename'] ) || !wp_verify_nonce( $_POST['site_settings_noncename'], plugin_basename( __FILE__ ) ) )
-            return;
-
-        // @TODO Refractor this with new custom capability
-        if ( !current_user_can( 'manage_options' ) )
-            return;
-
-	    update_post_meta( $post->ID, 'syn_transport_type', $_POST['transport_type'] );
-
-	    $site_enabled = isset( $_POST['site_enabled'] ) ? 'on' : 'off';
-	    $class = $_POST['transport_type'] . '_client';
-
-	    try {
-		    $save = wp_client_factory::save_client_settings( $post->ID, $class );
-		    if( !$save )
-			    return;
-		    $client = wp_client_factory::get_client( $_POST['transport_type'], $post->ID );
-
-		    if( $client->test_connection()  ) {
-                add_filter('redirect_post_location', create_function( '$location', 'return add_query_arg("message", 251, $location);' ) );
-            } else {
-			    $site_enabled = 'off';
-            }
-
-	    } catch( Exception $e ) {
-		    add_filter('redirect_post_location', create_function( '$location', 'return add_query_arg("message", 250, $location);' ) );
-	    }
-
-	    update_post_meta( $post->ID, 'syn_site_enabled', $site_enabled );
-
-    }
-
-	public function push_syndicate_admin_messages( $messages ) {
-
-		// general error messages
-		$messages['syn_site'][250] = __( 'Transport class not found!' );
-		$messages['syn_site'][251] = __( 'Connection Successful!' );
-
-		// xmlrpc error messages.
-		$messages['syn_site'][301] = __( 'Invalid URL.' );
-		$messages['syn_site'][302] = __( 'You do not have sufficient capability to perform this action.' );
-		$messages['syn_site'][303] = __( 'Bad login/pass combination.' );
-		$messages['syn_site'][304] = __( 'XML-RPC services are disabled on this site.' );
-		$messages['syn_site'][305] = __( 'Transport error. Invalid endpoint' );
-		$messages['syn_site'][306] = __( 'Something went wrong when connecting to the site.' );
-
-		// WordPress.com REST error messages
-		$messages['site'][301] = __( 'Invalid URL' );
-
-		return $messages;
-	}
-
-	/******* SYNDICATION METABOXES   *********/
-    public function add_post_metaboxes() {
-
-        // return if no post types supports push syndication
-        if( empty( $this->push_syndicate_settings[ 'selected_post_types' ] ) )
-            return;
-
-	    if ( !current_user_can( 'manage_options' ) )
-		    return;
-
-        $selected_post_types = $this->push_syndicate_settings[ 'selected_post_types' ];
-        foreach( $selected_post_types as $selected_post_type ) {
-            add_meta_box( 'syndicatediv', __( ' Syndicate ' ), array( &$this, 'add_syndicate_metabox' ), $selected_post_type, 'side', 'high' );
-	        //add_meta_box( 'syndicationstatusdiv', __( ' Syndication Status ' ), array( &$this, 'add_syndication_status_metabox' ), $selected_post_type, 'normal', 'high' );
-        }
-
-    }
-
-    public function add_syndicate_metabox( ) {
-
-	    global $post;
-
-	    // @TODO Refractor this with new custom capability
-	    if ( !current_user_can( 'manage_options' ) )
-		    return;
-
-        // nonce for verification when saving
-        wp_nonce_field( plugin_basename( __FILE__ ), 'syndicate_noncename' );
-
-        // get all sitegroups
-        $sitegroups = get_terms( 'syn_sitegroup', array(
-	        'fields' => 'all',
-	        'hide_empty' => false,
-	        'orderby' => 'name'
-        ) );
-
-        // if there are no sitegroups defined retrun
-        if( empty( $sitegroups ) ) {
-	        echo '<p>No sitegroups defined yet. You must group your sites into sitegroups to syndicate content</p>';
-	        echo '<p><a href="' . esc_url( get_admin_url() . 'edit-tags.php?taxonomy=sitegroups&post_type=site' ) . '" target="_blank" >Create new</a></p>';
-	        return;
-        }
-
-	    $selected_sitegroups = get_post_meta( $post->ID, '_syn_selected_sitegroups', true );
-	    $selected_sitegroups = !empty( $selected_sitegroups ) ? $selected_sitegroups : array() ;
-
-        echo '<ul>';
-
-        foreach( $sitegroups as $sitegroup  ) {
-
-?>
-	        <li>
-		        <label>
-			        <input type="checkbox" name="selected_sitegroups[]" value="<?php echo esc_html( $sitegroup->slug ); ?>" <?php $this->checked_array( $sitegroup->slug, $selected_sitegroups ) ?> />
-			        <?php echo esc_html( $sitegroup->name ); ?>
-		        </label>
-		        <p> <?php echo esc_html( $sitegroup->description ); ?> </p>
-	        </li>
-<?php
-
-        }
-
-        echo '</ul>';
-
-    }
-
-	public function checked_array( $sitegroup, $selected_sitegroups ) {
-		if( !empty( $selected_sitegroups ) ) {
-			if( in_array( $sitegroup, $selected_sitegroups ) ) {
-				echo 'checked="checked"';
-			}
-		}
-	}
-
-    public function save_syndicate_settings() {
-
-	    global $post;
-
-        // autosave verification
-        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
-            return;
-
-        // if our nonce isn't there, or we can't verify it return
-        if( !isset( $_POST['syndicate_noncename'] ) || !wp_verify_nonce( $_POST['syndicate_noncename'], plugin_basename( __FILE__ ) ) )
-            return;
-
-        // @TODO Refractor this with new custom capability
-        if ( !current_user_can( 'manage_options' ) )
-            return;
-
-	    $selected_sitegroups = !empty( $_POST['selected_sitegroups'] ) ? $_POST['selected_sitegroups'] : '' ;
-	    update_post_meta( $post->ID, '_syn_selected_sitegroups', $selected_sitegroups );
-
-    }
-
-	public function add_syndication_status_metabox() {
-		// @TODO retrieve syndication status and display
-	}
-
-	// @TODO scheduling happens before saving?
-	/*******    SYNCING CONTENT   *******/
-	public function schedule_syndicate_content_cron() {
-
-		global $post;
-
-		// autosave verification
-		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
-			return;
-
-		// if our nonce isn't there, or we can't verify it return
-		if( !isset( $_POST['syndicate_noncename'] ) || !wp_verify_nonce( $_POST['syndicate_noncename'], plugin_basename( __FILE__ ) ) )
-			return;
-
-		// @TODO Refractor this with new custom capability
-		if ( !current_user_can( 'manage_options' ) )
-			return;
-
-		$sites = $this->get_sites_by_post_ID( $post->ID );
-
-		wp_schedule_single_event(
-            time() - 1,
-            'syn_syndicate_content',
-			array( $sites )
-        );
-
-	}
-
-	// cron job function to syndicate content
-    public function syndicate_content( $sites ) {
-
-	    // if another process running on it return
-	    if( get_transient( 'syn_syndicate_lock' ) == 'locked' )
-			return
-
-	    // set value as locked, valid for 5 mins
-	    set_transient( 'syn_syndicate_lock', 'locked', 60*5 );
-
-	    /** start of critical section **/
-
-	    require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
-
-	    $post_ID = $sites[ 'post_ID' ];
-
-	    // an array containing states of sites
-	    $slave_post_states = get_post_meta( $post_ID, '_syn_slave_post_states', true );
-	    $slave_post_states = !empty( $slave_post_states ) ? $slave_post_states : array() ;
-
-	    if( !empty( $sites[ 'selected_sites' ] ) ) {
-
-	        foreach( $sites[ 'selected_sites' ] as $site ) {
-
-                $transport_type = get_post_meta( $site->ID, 'syn_transport_type', true);
-                $client = wp_client_factory::get_client( $transport_type  ,$site->ID );
-				$info = $this->get_site_info( $site->ID, $slave_post_states, $client );
-
-				if( $info['state'] == 'new' || $info['state'] == 'new-error' ) { // states 'new' and 'new-error'
-					$result = $client->new_post( $post_ID );
-					$this->validate_result_new_post( $result, $slave_post_states, $site->ID, $client );
-				} else { // states 'success', 'edit-error' and 'remove-error'
-					$result = $client->edit_post( $post_ID, $info['ext_ID'] );
-					$this->validate_result_edit_post( $result, $info, $slave_post_states, $site->ID, $client );
-				}
-
-	        }
-
-	    }
-
-	    if( !empty( $sites[ 'removed_sites' ]) ) {
-
-		    foreach( $sites[ 'removed_sites' ] as $site ) {
-
-			    $transport_type = get_post_meta( $site->ID, 'syn_transport_type', true);
-			    $client = wp_client_factory::get_client( $transport_type  ,$site->ID );
-			    $info = $this->get_site_info( $site->ID, $slave_post_states, $client );
-
-			    // if the post is not pushed we do not need to delete them
-			    if( $info['state'] == 'success' || $info['state'] == 'edit-error' || $info['state'] == 'remove-error' ) {
-
-				    $result = $client->delete_post( $info['ext_ID'] );
-				    if( !$result ) {
-					    $slave_post_states[ 'remove-error' ][ $site->ID ] = array(
-						    'error_code'    => $client->get_error_code(),
-						    'error_message' => $client->get_error_message()
-					    );
-				    }
-
-			    }
-
-		    }
-
-	    }
-
-        update_post_meta( $post_ID, '_syn_slave_post_states', $slave_post_states );
-
-	    /** end of critical section **/
-
-	    // release the lock.
-	    delete_transient( 'syn_syndicate_lock' );
-
-    }
-
-	public function get_sites_by_post_ID( $post_ID ) {
-
-		$selected_sitegroups = get_post_meta( $post_ID, '_syn_selected_sitegroups', true );
-		$selected_sitegroups = !empty( $selected_sitegroups ) ? $selected_sitegroups : array() ;
-
-		$old_sitegroups = get_post_meta( $post_ID, '_syn_old_sitegroups', true );
-		$old_sitegroups = !empty( $old_sitegroups ) ? $old_sitegroups : array() ;
-
-		$removed_sitegroups = array_diff( $old_sitegroups, $selected_sitegroups );
-
-		// initialization
-		$data = array(
-			'post_ID' => $post_ID,
-			'selected_sites' => array(),
-			'removed_sites' => array(),
-		);
-
-		if( !empty( $selected_sitegroups ) ) {
-
-			foreach( $selected_sitegroups as $selected_sitegroup ) {
-
-				// get all the sites in the sitegroup
-				$sites = $this->get_sites_by_sitegroup( $selected_sitegroup );
-				if( empty( $sites ) )
-					continue;
-
-				foreach( $sites as $site ) {
-					$site_enabled = get_post_meta( $site->ID, 'syn_site_enabled', true);
-					if( $site_enabled == 'on' ) {
-						$data[ 'selected_sites' ][] = $site;
-					}
-				}
-
-			}
-
-		}
-
-		if( !empty( $removed_sitegroups ) ) {
-
-			foreach( $removed_sitegroups as $removed_sitegroup ) {
-
-				// get all the sites in the sitegroup
-				$sites = $this->get_sites_by_sitegroup( $removed_sitegroup );
-				if( empty( $sites ) )
-					continue;
-
-				foreach( $sites as $site ) {
-					$site_enabled = get_post_meta( $site->ID, 'syn_site_enabled', true);
-					if( $site_enabled == 'on' ) {
-						$data[ 'removed_sites' ][] = $site;
-					}
-				}
-
-			}
-
-		}
-
-		update_post_meta( $post_ID, '_syn_old_sitegroups', $selected_sitegroups );
-
-		return $data;
-
-	}
-
-	// return an array of sites as objects based on sitegroup
-	public function get_sites_by_sitegroup( $sitegroup ) {
-
-		// @TODO if sitegroup is deleted?
-
-		$results = new WP_Query(array(
-			'post_type' => 'syn_site',
-			'posts_per_page' => -1, // retrieve all posts
-			'tax_query' => array(
-				array(
-					'taxonomy' => 'syn_sitegroup',
-					'field' => 'slug',
-					'terms' => $sitegroup
-				)
-			)
-		));
-
-		return $results->posts;
-
-	}
-
-	/**
-	 * $site_states is an array containing state of the site
-	 * with regard to the post the state. The states are
-	 *  success - the post was pushed successfully.
-	 *  new-error - error when creating the post.
-	 *  edit-error - error when editing the post.
-	 *  remove-error - error when removing the post in a slave site, when the sitegroup is unselected
-	 *  new - if the state is not found or the post is deleted in the slave site.
-	 */
-	public function get_site_info( $site_ID, &$slave_post_states, $client ) {
-
-		if( empty( $slave_post_states ) )
-			return array( 'state' => 'new' );
-
-		foreach( $slave_post_states as $state => $sites  ) {
-			if(   array_key_exists( $site_ID, $sites )   &&   !empty( $sites[ $site_ID ]['ext_ID'] )   ) {
-				if( $client->is_post_exists( $sites[ $site_ID ]['ext_ID'] ) ) {
-					$info = array( 'state' => $state, 'ext_ID' => $sites[ $site_ID ]['ext_ID'] );
-					unset( $slave_post_states[ $state ] [$site_ID] );
-					return $info;
-				} else {
-					return array( 'state' => 'new' );
-				}
-			}
-		}
-
-		return array( 'state' => 'new' );
-
-	}
-
-	/**
-	 * if the result is false state transitions
-	 * new          -> new-error
-	 * new-error    -> new-error
-	 * remove-error -> new-error
-	 */
-	public function validate_result_new_post( $result, &$slave_post_states, $site_ID, $client ) {
-
-		if( $result ) {
-			$slave_post_states[ 'success' ][ $site_ID ] = array(
-				'ext_ID'        => (int)$client->get_response()
-			);
-		} else {
-			$slave_post_states[ 'new-error' ][ $site_ID ] = array(
-				'error_code'    => $client->get_error_code(),
-				'error_message' => $client->get_error_message()
-			);
-		}
-
-	}
-
-	/**
-	 * if the result is false state transitions
-	 * edit-error   -> edit-error
-	 * success      -> edit-error
-	 */
-	public function validate_result_edit_post( $result, $info, &$slave_post_states, $site_ID, $client ) {
-
-		if( $result ) {
-			$slave_post_states[ 'success' ][ $site_ID ] = array(
-				'ext_ID'       => $info[ 'ext_ID' ]
-			);
-		} else {
-			$slave_post_states[ 'edit-error' ][ $site_ID ] = array(
-				'ext_ID'        => $info[ 'ext_ID' ],
-				'error_code'    => $client->get_error_code(),
-				'error_message' => $client->get_error_message()
-			);
-		}
-
-	}
-
-	/*******  DELETING CONTENT   *******/
-	public function delete_slave_posts( $post_ID ) {
-
-		// if slave post deletion is not enabled return
-		$delete_pushed_posts =  !empty( $this->push_syndicate_settings[ 'delete_pushed_posts' ] ) ? $this->push_syndicate_settings[ 'delete_pushed_posts' ] : 'off' ;
-		if( $delete_pushed_posts != 'on' )
-			return;
-
-		wp_schedule_single_event(
-			time() - 1,
-			'syn_delete_content',
-			array( $post_ID )
-		);
-
-	}
-
-	public function delete_content( $post_ID ) {
-
-		require_once( dirname( __FILE__ ) . '/includes/class-wp-client-factory.php' );
-
-		$delete_error_sites = get_option( 'syn_delete_error_sites' );
-		$delete_error_sites = !empty( $delete_error_sites ) ? $delete_error_sites : array() ;
-		$slave_posts = $this->get_slave_posts( $post_ID );
-
-		if( empty( $slave_posts ) )
-			return;
-
-		foreach( $slave_posts as $site_ID => $ext_ID ) {
-
-			$site_enabled = get_post_meta( $site_ID, 'syn_site_enabled', true);
-
-			// check whether the site is enabled
-			if( $site_enabled == 'on' ) {
-
-				$transport_type = get_post_meta( $site_ID, 'syn_transport_type', true);
-				$client = wp_client_factory::get_client( $transport_type , $site_ID );
-
-				if( $client->is_post_exists( $ext_ID ) ) {
-
-					$result = $client->delete_post( $ext_ID );
-					if( !$result ) {
-						$delete_error_sites[ $site_ID ] = array( $ext_ID );
-					}
-
-				}
-
-			}
-
-		}
-
-		update_option( 'syn_delete_error_sites', $delete_error_sites );
-		// all post metadata will be automatically deleted including slave_post_states
-
-	}
-
-	// get the slave posts as $site_ID => $ext_ID
-	public function get_slave_posts( $post_ID ) {
-
-		// array containing states of sites
-		$slave_post_states = get_post_meta( $post_ID, '_syn_slave_post_states', true );
-
-		// array containing slave posts as $site_ID => $ext_ID
-		$slave_posts = array();
-
-		foreach( (array)$slave_post_states as $state ) {
-			foreach( $state as $site_ID => $info ) {
-				if( !empty( $info[ 'ext_ID' ] ) ) {
-					$slave_posts[ $site_ID ] = $info[ 'ext_ID' ];
-				}
-			}
-		}
-
-		return $slave_posts;
-
-	}
-
-}
 
 $Push_Syndication_Server = new Push_Syndication_Server();