/// <summary>
        ///
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="iter"></param>
        private void AppendTokens(SqlStringBuilder builder, ICollection iter)
        {
            bool lastSpaceable = true;
            bool lastQuoted    = false;

            int debugIndex = 0;

            foreach (object token in iter)
            {
                string    tokenString    = token as string;
                SqlString tokenSqlString = token as SqlString;

                bool spaceable = !dontSpace.Contains(token);
                bool quoted    = false;

                //TODO: seems HACKish to cast between String and SqlString
                if (tokenString != null)
                {
                    quoted = tokenString.StartsWith("'");
                }
                else
                {
                    quoted = tokenSqlString.StartsWith("'");
                }

                if (spaceable && lastSpaceable)
                {
                    if (!quoted || !lastQuoted)
                    {
                        builder.Add(" ");
                    }
                }

                lastSpaceable = spaceable;

                if (token.Equals(StringHelper.SqlParameter))
                {
                    Parameter param = new Parameter("placeholder");
                    builder.Add(param);
                }
                else
                {
                    // not sure if we have a string or a SqlString here and token is a
                    // reference to an object - so let the builder figure out what the
                    // actual object is
                    builder.AddObject(token);
                }
                debugIndex++;

                if (tokenString != null)
                {
                    lastQuoted = tokenString.EndsWith("'");
                }
                else
                {
                    lastQuoted = tokenSqlString.EndsWith("'");
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="condition"></param>
        public override void AddCondition(SqlString condition)
        {
            //TODO: this seems hackish
            if (
                afterFrom.ToSqlString().ToString().IndexOf(condition.Trim().ToString()) < 0 &&
                afterWhere.ToSqlString().ToString().IndexOf(condition.Trim().ToString()) < 0)
            {
                if (!condition.StartsWith(" and "))
                {
                    afterWhere.Add(" and ");
                }

                afterWhere.Add(condition);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="fragment"></param>
        public void AddSelectFragmentString(SqlString fragment)
        {
            if (fragment.SqlParts.Length > 0 && fragment.StartsWith(","))
            {
                fragment = fragment.Substring(1);
            }

            fragment = fragment.Trim();

            if (fragment.SqlParts.Length > 0)
            {
                if (selectBuilder.Count > 0)
                {
                    selectBuilder.Add(StringHelper.CommaSpace);
                }

                selectBuilder.Add(fragment);
            }
        }
        /// <summary></summary>
        public SqlString ToQuerySqlString()
        {
            SqlStringBuilder builder = new SqlStringBuilder();

            builder.Add("select ");

            if (distinct)
            {
                builder.Add("distinct ");
            }

            SqlString from = joins.ToFromFragmentString;

            if (from.StartsWith(","))
            {
                from = from.Substring(1);
            }
            else if (from.StartsWith(" inner join"))
            {
                from = from.Substring(11);
            }

            builder.Add(selectBuilder.ToSqlString())
            .Add(" from")
            .Add(from);

            SqlString part1    = joins.ToWhereFragmentString.Trim();
            SqlString part2    = whereBuilder.ToSqlString().Trim();
            bool      hasPart1 = part1.SqlParts.Length > 0;
            bool      hasPart2 = part2.SqlParts.Length > 0;

            if (hasPart1 || hasPart2)
            {
                builder.Add(" where ");
            }
            if (hasPart1)
            {
                builder.Add(part1.Substring(4));
            }
            if (hasPart2)
            {
                if (hasPart1)
                {
                    builder.Add(" and (");
                }
                builder.Add(part2);
                if (hasPart1)
                {
                    builder.Add(")");
                }
            }
            if (groupBy.Length > 0)
            {
                builder.Add(" group by ").Add(groupBy.ToString());
            }
            if (having.Length > 0)
            {
                builder.Add(" having ").Add(having.ToString());
            }
            if (orderBy.Length > 0)
            {
                builder.Add(" order by ").Add(orderBy.ToString());
            }
            return(builder.ToSqlString());
        }
		public void StartsWithEmptyString() 
		{
			SqlString sql = new SqlString( new string[] { "", "select", " from table" } );
			Assert.IsTrue( sql.StartsWith("s") );
			Assert.IsFalse( sql.StartsWith(",") );
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="fragment"></param>
		public void AddSelectFragmentString( SqlString fragment )
		{
			if( fragment.SqlParts.Length > 0 && fragment.StartsWith( "," ) )
			{
				fragment = fragment.Substring( 1 );
			}

			fragment = fragment.Trim();

			if( fragment.SqlParts.Length > 0 )
			{
				if( selectBuilder.Count > 0 )
				{
					selectBuilder.Add( StringHelper.CommaSpace );
				}

				selectBuilder.Add( fragment );
			}
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="condition"></param>
		public override void AddCondition( SqlString condition )
		{
			//TODO: this seems hackish
			if(
				afterFrom.ToSqlString().ToString().IndexOf( condition.Trim().ToString() ) < 0 &&
					afterWhere.ToSqlString().ToString().IndexOf( condition.Trim().ToString() ) < 0 )
			{
				if( !condition.StartsWith( " and " ) )
				{
					afterWhere.Add( " and " );
				}

				afterWhere.Add( condition );
			}
		}