/// <summary>
        /// Removes a movie criteria from a node
        /// </summary>
        /// <param name="movie">The movie to remove from the nodes criteria filter</param>
        /// <param name="rootNode">The node that the criteria filter belongs to</param>
        static void RemoveMovieCriteriaFromNode(DBNode<DBMovieInfo> node, string movieId)
        {
            if (!BasicHandler.IsValidImdb(movieId))
                return;

            if (!node.HasFilter || string.IsNullOrEmpty(movieId)) return;

            // find critera match in the nodes filter and then remove
            var criteria = node.Filter.Criteria.FirstOrDefault(c => c.Value.ToString() == movieId);
            if (criteria != null)
                node.Filter.Criteria.Remove(criteria);

            if (node.Filter.Criteria.Count == 0)
            {
                TraktLogger.Info("Adding dummy blacklist criteria to the child '{0}' node filter.", node.Name);
                AddDummyBlacklistToFilter(node.Filter);
            }

            node.Commit();
        }
        /// <summary>
        /// Add criteria (IMDb ID's) for a movie list to a nodes filter criteria
        /// We don't need to worry about movies that don't exist as they will simply not be visible
        /// </summary>
        /// <param name="name">Name of child node to add filters to</param>
        /// <param name="movieIMDbList">List of IMDb ID's to add </param>
        static void AddMoviesCriteriaToNode(DBNode<DBMovieInfo> node, IEnumerable<string> movieIMDbList)
        {
            if (node == null) return;

            // remove any movies that don't contain IMDb ID's.
            var imdbCriteraToAdd = movieIMDbList.Where(s => !string.IsNullOrEmpty(s)).ToList();

            // clear existing filter
            if (node.HasFilter)
            {
                // do a quick check to see if we need to do anything
                // if the criteria counts matches, determine if the critera values also matches
                if (node.Filter.Criteria.Count == imdbCriteraToAdd.Count)
                {
                    bool requiresUpdate = false;
                    foreach (var criteria in node.Filter.Criteria)
                    {
                        // no point doing any further checks
                        if (requiresUpdate)
                            continue;

                        // check if the current critera list already has the criteria in the filter
                        requiresUpdate = !imdbCriteraToAdd.Contains(criteria.Value.ToString());
                    }

                    // nothing to do with node, it's already up to date
                    if (!requiresUpdate)
                        return;
                }

                node.Filter.WhiteList.Clear();
                node.Filter.BlackList.Clear();
                node.Filter.Delete();
            }

            // create a new filter, such that any criteria will match
            node.Filter = new DBFilter<DBMovieInfo>();
            node.Filter.CriteriaGrouping = DBFilter<DBMovieInfo>.CriteriaGroupingEnum.ONE;
            node.Filter.Name = string.Format("{0} Filter", node.Name);

            // add criteria for each movie
            foreach (var movieId in imdbCriteraToAdd)
            {
                //TraktLogger.Debug("Adding criteria to the '{0}' node filter, Field = 'imdb_id', Value = '{1}'", node.Name, movieId);

                var criteria = new DBCriteria<DBMovieInfo>();
                criteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "imdb_id");
                criteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
                criteria.Value = movieId;

                // add the criteria to the filter
                node.Filter.Criteria.Add(criteria);
            }

            if (node.Filter.Criteria.Count == 0)
            {
                TraktLogger.Info("Adding dummy blacklist criteria to the '{0}' node filter.", node.Name);
                AddDummyBlacklistToFilter(node.Filter);
            }

            node.Commit();
        }
        /// <summary>
        /// Created a child node
        /// </summary>
        /// <param name="rootNode">The parent node to create a node under</param>
        /// <param name="name">Name of new child node</param>
        /// <returns>Returns the existing child node if it exists otherwise creates a new one</returns>
        static DBNode<DBMovieInfo> CreateNode(DBNode<DBMovieInfo> rootNode, string name, bool createBlacklist = false)
        {
            if (rootNode == null) return null;

            string nodeName = name;
            if (!nodeName.StartsWith("$"))
                nodeName = string.Format("${{{0}}}", name);

            // check if the node exists, if not create it
            var node = rootNode.Children.FirstOrDefault(n => n.Name == nodeName);

            // we have it, nothing else to do
            if (node != null)
                return node;

            TraktLogger.Info("Creating child node '{0}' under Trakt", name);

            // create the node with default settings
            node = new DBNode<DBMovieInfo> { Name = nodeName };

            var nodeSettings = new DBMovieNodeSettings();
            node.AdditionalSettings = nodeSettings;

            if (createBlacklist)
            {
                TraktLogger.Info("Adding dummy blacklist criteria to the '{0}' node filter", name);
                node.Filter = new DBFilter<DBMovieInfo>();
                node.Filter.CriteriaGrouping = DBFilter<DBMovieInfo>.CriteriaGroupingEnum.ONE;
                node.Filter.Name = string.Format("{0} Filter", nodeName);
                AddDummyBlacklistToFilter(node.Filter);
            }

            // add as a child to the root node
            node.Parent = rootNode;
            rootNode.Children.Add(node);
            rootNode.Commit();

            return node;
        }
        /// <summary>
        /// Adds a movie criteria to a node
        /// </summary>
        /// <param name="node">Node to add movie criteria to</param>
        /// <param name="movieId">IMDb movie ID used for the criteria</param>
        static void AddMovieCriteriaToNode(DBNode<DBMovieInfo> node, string movieId)
        {
            if (node == null || !BasicHandler.IsValidImdb(movieId)) return;

            // check existing filter exists
            if (!node.HasFilter) return;

            // add movie id as a criteria
            var criteria = new DBCriteria<DBMovieInfo>();
            criteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "imdb_id");
            criteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
            criteria.Value = movieId;

            // add the criteria to the filter
            node.Filter.Criteria.Add(criteria);
            node.Commit();
        }