QList<FakeJobResponse *> FakeJobResponse::parseTreeString( FakeServerData *fakeServerData, const QString& treeString)
{
  int depth = 0;

  QList<FakeJobResponse *> collectionResponseList;
  QHash<Collection::Id, FakeJobResponse *> itemResponseMap;

  Collection::List recentCollections;

  recentCollections.append( Collection::root() );

  QList<Token> tokens = tokenize( treeString );
  while(!tokens.isEmpty())
  {
    Token token = tokens.takeFirst();

    if (token.type == Token::Branch)
    {
      ++depth;
      continue;
    }
    Q_ASSERT(token.type == Token::Leaf);
    parseEntityString( collectionResponseList, itemResponseMap, recentCollections, fakeServerData, token.content, depth );

    depth = 0;
  }
  return collectionResponseList;
}
void FakeJobResponse::parseEntityString( QList<FakeJobResponse *> &collectionResponseList, QHash<Collection::Id, FakeJobResponse *> &itemResponseMap, Collection::List &recentCollections, FakeServerData *fakeServerData, const QString& _entityString, int depth )
{
  QString entityString = _entityString;
  if ( entityString.startsWith( 'C' ) )
  {
    Collection collection;
    entityString.remove( 0, 2 );
    Q_ASSERT( entityString.startsWith( '(' ) );
    entityString.remove( 0, 1 );
    QStringList parts = entityString.split( ')' );

    if ( !parts.first().isEmpty() )
    {
      QString typesString = parts.takeFirst();

      QStringList types = typesString.split(',');
      types.replaceInStrings(" ", "");
      collection.setContentMimeTypes( types );
    } else {
      parts.removeFirst();
    }

    collection.setId( fakeServerData->nextCollectionId() );
    collection.setName( QString("Collection %1").arg( collection.id() ) );
    collection.setRemoteId( QString( "remoteId %1" ).arg( collection.id() ) );

    if ( depth == 0 )
      collection.setParentCollection( Collection::root() );
    else
      collection.setParentCollection( recentCollections.at( depth ) );

    if ( recentCollections.size() == ( depth + 1) )
      recentCollections.append( collection );
    else
      recentCollections[ depth + 1 ] = collection;

    int order = 0;
    if ( !parts.first().isEmpty() )
    {
      QString displayName;
      QString optionalSection = parts.first().trimmed();
      if ( optionalSection.startsWith( QLatin1Char( '\'' ) ) )
      {
        optionalSection.remove( 0, 1 );
        QStringList optionalParts = optionalSection.split( QLatin1Char( '\'' ) );
        displayName = optionalParts.takeFirst();
        EntityDisplayAttribute *eda = new EntityDisplayAttribute();
        eda->setDisplayName( displayName );
        collection.addAttribute( eda );
        optionalSection = optionalParts.first();
      }

      QString orderString = optionalSection.trimmed();
      if ( !orderString.isEmpty() )
      {
        bool ok;
        order = orderString.toInt(&ok);
        Q_ASSERT(ok);
      }
    } else
    {
      order = 1;
    }
    while ( collectionResponseList.size() < order )
    {
      collectionResponseList.append( new FakeJobResponse( recentCollections[ depth ], FakeJobResponse::RespondToCollectionFetch, fakeServerData ) );
    }
    collectionResponseList[ order - 1 ]->appendCollection( collection );
  }
  if ( entityString.startsWith( 'I' ) )
  {
    Item item;
    entityString.remove( 0, 2 );
    entityString = entityString.trimmed();
    QString type;
    int order = 0;
    int iFirstSpace = entityString.indexOf( QLatin1Char( ' ' ) );
    type = entityString.left( iFirstSpace );
    entityString = entityString.remove( 0, iFirstSpace + 1 ).trimmed();
    if ( iFirstSpace > 0 && !entityString.isEmpty() )
    {
      QString displayName;
      QString optionalSection = entityString;
      if ( optionalSection.startsWith( QLatin1Char( '\'' ) ) )
      {
        optionalSection.remove( 0, 1 );
        QStringList optionalParts = optionalSection.split( QLatin1Char( '\'' ) );
        displayName = optionalParts.takeFirst();
        EntityDisplayAttribute *eda = new EntityDisplayAttribute();
        eda->setDisplayName( displayName );
        item.addAttribute( eda );
        optionalSection = optionalParts.first();
      }
      QString orderString = optionalSection.trimmed();
      if ( !orderString.isEmpty() )
      {
        bool ok;
        order = orderString.toInt( &ok );
        Q_ASSERT( ok );
      }
    } else
      type = entityString;

    item.setMimeType( type );
    item.setId( fakeServerData->nextItemId() );
    item.setRemoteId( QString( "RId_%1 %2" ).arg( item.id() ).arg(type) );
    item.setParentCollection( recentCollections.at( depth ) );

    Collection::Id colId = recentCollections[ depth ].id();
    if ( !itemResponseMap.contains( colId ) )
    {
      FakeJobResponse *newResponse = new FakeJobResponse( recentCollections[ depth ], FakeJobResponse::RespondToItemFetch, fakeServerData );
      itemResponseMap.insert( colId, newResponse );
      collectionResponseList.append( newResponse );
    }
    itemResponseMap[ colId ]->appendItem( item );
  }
}