char * str_replace ( char *pNeedle, char *pReplace, char *pSubject )
{
  if ( !pNeedle || !pReplace || !pSubject )
    return NULL;

  bool bFound = false;
  char *pRet = strdup ( pSubject );
  int nOffset = 0;

  do
  {
    char *pFound = strstr( pRet + nOffset, pNeedle );

    if ( pFound )
      bFound = true;
    else
      bFound = false;

    if ( bFound )
    {
      if ( strlen ( pNeedle ) == strlen ( pReplace ) )
      {                
        memmove ( pRet + ( pFound - pRet ), ( const void *) pReplace, strlen ( pReplace ) );   
        nOffset = ( pFound - pRet ) + strlen( pNeedle );
      }
      else 
      {
        int nOldLen = strlen ( pRet );
        int nNewLen = strlen ( pRet ) + ( -1 * ( strlen ( pNeedle ) - strlen ( pReplace ) ) ) ;

        char *pszTemp = new char [ nNewLen + 1 ];
        if ( !pszTemp )
          return false;

        memset ( pszTemp, 0, nNewLen );

        int nX = pFound - pRet;
        memmove ( pszTemp, pRet, nX );
        memmove ( pszTemp + nX, pReplace, strlen ( pReplace ) );        
        memmove ( pszTemp + nX + strlen ( pReplace ), pRet + nX + strlen ( pNeedle ), strlen ( pRet + nX + strlen ( pNeedle ) ) );
        
        memset ( pszTemp + nNewLen, 0, sizeof ( char ) );

        delete[] pRet ;
        pRet = pszTemp;
        
        nOffset =  nX + strlen ( pReplace );
      }
    }
  } while ( bFound );

  return pRet;
}