text:
'use strict'

var factories = angular.module('relay.factories', [
  'restangular'
]);

factories.factory('feedManager', ['Restangular', function(Restangular){

  return {
    getPopularPosts: function(){
      return Restangular.all('posts').customGETLIST('popular').$object;
    },

    getUserFeed: function(user){
      return Restangular.one("users", user._id).customGETLIST('feed').$object;
    }
  };

}]);

factories.factory('userManager', ['$rootScope', 'Restangular', 'GuestUser', 'User',
                  function($rootScope, Restangular, GuestUser, User){

  return {
    setCurrentUser: function(){
      $rootScope.isUserLoggedIn = false;
      $rootScope.currentUser = new GuestUser();
      Restangular.one('loggedIn').get().then(function(user){
        $rootScope.currentUser    = new User(user);
        $rootScope.isUserLoggedIn = true;
      });
    }
  };

}]);

factories.factory('postManager', ['$rootScope', 'Restangular', function($rootScope, Restangular){

  return {
    userRelayPost: function(user, post){
      Restangular.one('posts', post._id)
        .post('relay', {relayer: user._id} )
        .then(function(){
          console.log("userRelayPost successful");
        }, function(){
          console.error("Error: userRelayPost unsuccessful");
        });
    },

    userUnrelayPost: function(user, post){
      Restangular.one('posts', post._id)
        .post('unrelay', {relayer: user._id} )
        .then(function(){
          console.log("userUnrelayPost successful");
        }, function(){
          console.error("Error: userRelayPost unsuccessful");
        });
    }
  };

}]);

factories.factory('Post', function(){

  function Post(data){
    data = data || {};
    angular.extend(this, data);
    this.feedItem = data.feedItem || {};
    this.relayed  = this.feedItem.relayed || data.relayed || false;
    this.feedStatus = function() {
      if (this.relayed) return 'relayed';
      else return null;
    };
  }

  return Post;
});

factories.factory('User', ['postManager', function(postManager){

  function User(data){
    angular.extend(this, {
      relayPost: function(post){
        postManager.userRelayPost(this, post);
      },

      unrelayPost: function(post){
        postManager.userUnrelayPost(this, post);
      }
    });

    angular.extend(this, data);
  }

  return User;
}]);

factories.factory('GuestUser', ['User', function(User){

  function GuestUser(data) {
    angular.extend(this, {
      deferredRelays:      {},
      deferRelay:          function(post) { this.deferredRelays[post.id] = post },
      removeDeferredRelay: function(post) { delete this.deferredRelays[post.id] }
    });

    // Inherit from User
    angular.extend(this, User);
    // Override User relayPost function
    this.relayPost = this.deferRelay;
    this.unrelayPost = this.deferRelay;
  }

  return GuestUser;
}]);

factories.factory('urlImageExtractor', ['urlValidator', 'Restangular', function(urlValidator, Restangular){
  return {
    fetchImageUrlFromUrl: function(url, done){
      url = urlValidator.normalizedUrl(url);
      var encodedUrl = encodeURIComponent(url);
      Restangular
        .one('utils')
        .customGET('getImageUrl', {url: encodedUrl} )
        .then(function(res){
          console.log(res.url);
          done(res.url);
        });
    }
  };
}]);

factories.factory('urlValidator', function(){
  var linkExp         = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/
    , httpProtocolExp = new RegExp("^https?://.+")
    , wwwExp          = new RegExp("^www\..+");

  var hasHost = function(url){
    return wwwExp.test(url) || httpProtocolExp.test(url);
  };

  return {
    isUrl: function(str){
      return hasHost(str) && linkExp.test(str);
    },

    normalizedUrl: function(url){
      if (!this.isUrl(url)) return null;
      return !httpProtocolExp.test(url) ? "http://"+url : url;
    }
  };
});


text:
actions :accept
default_action :accept

redpajama_set_name: RedPajamaGithub


text:
<?php defined('C5_EXECUTE') or die("Access Denied.");
/* @var $h ConcreteDashboardHelper */
$h = Loader::helper('concrete/dashboard');
/* @var $ih ConcreteInterfaceHelper */
$ih = Loader::helper('concrete/interface');
/* @var $form FormHelper */
$form = Loader::helper('form');
/* @var $jh JsonHelper */
$jh = Loader::helper('json');
/* @var $dh DateHelper */
$dh = Loader::helper('date');

?>

<?=$h->getDashboardPaneHeaderWrapper(t('Automated Jobs'), false, false);?>

<?=Loader::helper('concrete/interface')->tabs(array(
	array($this->action('view'), t('Jobs'), $jobListSelected),
	array($this->action('view_sets'), t('Job Sets'), $jobSetsSelected)
), false);?>

<? if (in_array($this->controller->getTask(), array('view', 'install', 'uninstall', 'job_installed', 'job_uninstalled', 'reset', 'reset_complete', 'job_scheduled'))) { ?>

<? if (count($installedJobs) > 0) { ?>

		<?=t('ID')?>
		<?=t('Name')?>
		<?=t('Last Run')?>
		<?=t('Results of Last Run')?>
		<a href="<?=$this->action('reset')?>" class="btn pull-right btn-mini"><?=t('Reset All Jobs')?>

	<? foreach($installedJobs as $j) { ?>
		<tr class="<? if ($j->didFail()) { ?>error<? } ?> <? if ($j->getJobStatus() == 'RUNNING') {?>running<? } ?>">
			<?=$j->getJobID()?>
			<i class="icon-question-sign" title="<?=$j->getJobDescription()?>"> <?=$j->getJobName()?>
			<?
				if ($j->getJobStatus() == 'RUNNING') {
					$runtime = $dh->date(DATE_APP_GENERIC_MDYT_FULL_SECONDS, strtotime($j->getJobDateLastRun()));
					echo ("");
					echo t("Running since %s", $runtime);
					echo ("");
				} else if($j->getJobDateLastRun() == '' || substr($j->getJobDateLastRun(), 0, 4) == '0000') {
					echo t('Never');
				} else {
					$runtime = $dh->date(DATE_APP_GENERIC_MDYT_FULL_SECONDS, strtotime($j->getJobDateLastRun()) );
					echo $runtime;
				}
			?>
			<?=$j->getJobLastStatusText()?>

				<button data-jID="<?=$j->getJobID()?>" data-jSupportsQueue="<?=$j->supportsQueue()?>" data-jName="<?=$j->getJobName()?>" class="btn-run-job btn-small btn"> <?=t('Run')?></button>

				<a href="javascript:void(0)" class="ccm-automate-job-instructions" data-jSupportsQueue="<?=$j->supportsQueue()?>" data-jID="<?=$j->getJobID()?>" title="<?=t('Automate this Job')?>">
				<? if ($j->canUninstall()) { ?>
					<a href="<?=$this->action('uninstall', $j->getJobID())?>" title="<?=t('Remove this Job')?>">
				<? } ?>

	<? } ?>

<? foreach($installedJobs as $j) { ?>
	<div id="jd<?=$j->getJobID()?>" class="ccm-ui">
		<form action="<?=$this->action('update_job_schedule')?>" method="post">
			<?=$form->hidden('jID', $j->getJobID());?>

<?=t('Run Job')?>

				<input type="radio" name="isScheduled" class="ccm-jobs-automation-schedule-type" value="1" <?=($j->isScheduled?'checked="checked"':'')?> />
				<?=t('When people browse to the page.  (which runs after the main rendering request of the page.)')?>

			<fieldset class="ccm-jobs-automation-schedule-auto" <?=($j->isScheduled?'':'style="display: none;"')?>>

						<?php  echo t('Run this Job Every')?>

							<?php echo $form->text('value',$j->scheduledValue,array('class'=>'span2'))?>
							<?php echo $form->select('unit', array('hours'=>t('Hours'), 'days'=>t('Days'), 'weeks'=>t('Weeks'), 'months'=>t('Months')), $j->scheduledInterval, array('class'=>'span2'))?>

			</fieldset>

				<input type="radio" name="isScheduled" class="ccm-jobs-automation-schedule-type" value="0" <?=($j->isScheduled?'':'checked="checked"')?> />
				<?=t('Through Cron')?>

			<fieldset class="ccm-jobs-automation-schedule-cron" <?=($j->isScheduled?'style="display: none;"':'')?>>

					<? if ($j->supportsQueue()) { ?>

<?=t('The "%s" job supports queueing, meaning it can be run in a couple different ways:', $j->getJobName())?>

<?=t('No Queueing')?>

<textarea style="width: 560px" rows="2" class="ccm-default-jobs-url"><?=BASE_URL . $this->url('/tools/required/jobs?auth=' . $auth . '&jID=' . $j->getJobID())?></textarea>

<?=t('This will treat the job as though it were like any other concrete5 job. The entire job will be run at once.')?>

<?=t('Queueing')?>

<?=t("First, schedule this URL for when you'd like this job to run:")?>

<textarea style="width: 560px" rows="2" class="ccm-default-jobs-url"><?=BASE_URL . REL_DIR_FILES_TOOLS_REQUIRED . '/jobs/run_single?auth=' . $auth . '&jID=' . $j->getJobID()?></textarea>

<?=t('Then, make sure this URL is scheduled to run frequently, like every 3-5 minutes:')?>

<textarea style="width: 560px" rows="2" class="ccm-default-jobs-url"><?=BASE_URL . REL_DIR_FILES_TOOLS_REQUIRED . '/jobs/check_queue?auth=' . $auth?></textarea>

<?=t('The first URL starts the process - the second ensures that it completes in batches.')?>

					<? } else { ?>

<?=t('To run the "%s" job, automate the following URL using cron or a similar system:', $j->getJobName())?>

<textarea style="width: 560px" rows="2" class="ccm-default-jobs-url"><?=BASE_URL . $this->url('/tools/required/jobs/run_single?auth=' . $auth . '&jID=' . $j->getJobID())?></textarea>

					<? } ?>

			</fieldset>

					<input type="submit" value="<?php echo t('Save'); ?>" class="btn ccm-button-v2 primary ccm-button-v2-right">

		</form>

<? } ?>

<? } else { ?>

<?=t('You have no jobs installed.')?>

<? } ?>

<? if (count($availableJobs) > 0) { ?>

<?=t('Awaiting Installation')?>

			<?=t('Name')?>
			<?=t('Description')?>

		<?foreach($availableJobs as $availableJobName => $job):?>

			<?=$job->getJobName() ?>
			<?=$job->getJobDescription() ?>
			<?if(!$job->invalid):?>
				<a href="<?=$this->action('install', $job->jHandle)?>" class="btn btn-small pull-right"><?=t('Install')?>
			<?endif?>

		<?endforeach?>

<? } ?>
<?
$djs = JobSet::getDefault();
if (is_object($djs)) { ?>

<?=t('Automation Instructions')?>

<?=t('To run all the jobs in the %s Job Set, schedule this URL using cron or a similar system:', $this->url('/dashboard/system/optimization/jobs', 'edit_set', $djs->getJobSetID()), $djs->getJobSetDisplayName())?>

<input type="text" style="width: 700px" class="ccm-default-jobs-url" value="<?=BASE_URL . $this->url('/tools/required/jobs?auth=' . $auth)?>" />

<? } ?>

<? } else { ?>

<?php if (in_array($this->controller->getTask(), array('update_set', 'update_set_jobs', 'edit_set', 'delete_set'))) { ?>

		<form class="form-vertical" method="post" action="<?php echo $this->action('update_set')?>">

			<input type="hidden" name="jsID" value="<?php echo $set->getJobSetID()?>" />

			<?php echo Loader::helper('validation/token')->output('update_set')?>

		<fieldset>
			<legend><?=t('Details')?></legend>

				<?php echo $form->label('jsName', t('Name'))?>

					<?php echo $form->text('jsName', $set->getJobSetName())?>

					<?php echo $form->submit('submit', t('Update Set'), array('class' => ''))?>

		</fieldset>
		</form>

		<? if ($set->canDelete()) { ?>

		<form method="post" action="<?php echo $this->action('delete_set')?>" class="form-vertical">
		<fieldset>
			<legend><?=t('Delete Set')?></legend>

<?php echo t('Warning, this cannot be undone. No jobs will be deleted but they will no longer be grouped together.')?>

			<input type="hidden" name="jsID" value="<?php echo $set->getJobSetID()?>" />
			<?php echo Loader::helper('validation/token')->output('delete_set')?>

				<?php echo $form->submit('submit', t('Delete Job Set'), array('class' => 'danger'))?>

		</fieldset>
		</form>
		<? } ?>

		<form class="form-vertical" method="post" action="<?php echo $this->action('update_set_jobs')?>">
			<input type="hidden" name="jsID" value="<?php echo $set->getJobSetID()?>" />
			<?php echo Loader::helper('validation/token')->output('update_set_jobs')?>

		<fieldset>
			<legend><?=t('Jobs')?></legend>

			<?php
			$list = $set->getJobs();
			if (count($installedJobs) > 0) { ?>

						<?php foreach($installedJobs as $g) {

						?>

									<?php echo $form->checkbox('jID[]', $g->getJobID(), $set->contains($g)) ?>
									<?php echo $g->getJobName()?>

						<?php } ?>

					<?php echo $form->submit('submit', t('Update Jobs'), array('class' => ''))?>

			<?php } else { ?>

<?php echo t('No Jobs found.')?>

			<?php } ?>
		</fieldset>
		</form>

<?=t('Automation Instructions')?>

			<form action="<?=$this->action('update_set_schedule');?>" method="post">
				<?=$form->hidden('jsID',$set->getJobSetID()); ?>

				<input type="radio" name="isScheduled" class="ccm-jobs-automation-schedule-type" value="1" <?=($set->isScheduled?'checked="checked"':'')?> />
				<?=t('When people browse to the page.  (which runs after the main rendering request of the page.)')?>

			<fieldset class="ccm-jobs-automation-schedule-auto" <?=($set->isScheduled?'':'style="display: none;"')?>>

					<?php  echo t('Run this Job Every')?>

						<?php echo $form->text('value',$set->scheduledValue,array('class'=>'span2'))?>
						<?php echo $form->select('unit', array('hours'=>t('Hours'), 'days'=>t('Days'), 'weeks'=>t('Weeks'), 'months'=>t('Months')), $set->scheduledInterval, array('class'=>'span2'))?>

			</fieldset>

				<input type="radio" name="isScheduled" class="ccm-jobs-automation-schedule-type" value="0" <?=($set->isScheduled?'':'checked="checked"')?> />
				<?=t('Through Cron')?>

			<fieldset class="ccm-jobs-automation-schedule-cron" <?=($set->isScheduled?'style="display: none;"':'')?>>

<?=t('To run all the jobs in this Job Set, schedule this URL using cron or a similar system:', $set->getJobSetID())?>

<textarea style="width: 560px" rows="2" class="ccm-default-jobs-url"><?=BASE_URL . $this->url('/tools/required/jobs?auth=' . $auth . '&jsID=' . $set->getJobSetID())?></textarea>

			</fieldset>

				<?php echo $form->submit('submit', t('Update Schedule'), array('class' => ''))?>

			</form>

<? } else { ?>

	<form method="post" class="form-horizontal" action="<?php echo $this->action('add_set')?>">

	<?php if (count($jobSets) > 0) { ?>

			<?php foreach($jobSets as $j) { ?>
				<div class="ccm-group" id="asID_<?php echo $j->getJobSetID()?>">
					<a class="ccm-group-inner" href="<?php echo $this->url('/dashboard/system/optimization/jobs', 'edit_set', $j->getJobSetID())?>" style="background-image: url(<?php echo ASSETS_URL_IMAGES?>/icons/group.png)"><?php echo $j->getJobSetDisplayName()?>

			<?php } ?>

	<?php } else { ?>

<?php echo t('You have not added any Job sets.')?>

	<?php } ?>

<?=t('Add Set')?>

	<?php echo Loader::helper('validation/token')->output('add_set')?>

		<?php echo $form->label('jsName', t('Name'))?>

			<?php echo $form->text('jsName')?>

		<?=t('Jobs')?>

		<? foreach($installedJobs as $j) { ?>
			<?=$form->checkbox('jID[]', $j->getJobID())?> <?=$j->getJobName()?>
		<? } ?>

			<?php echo $form->submit('submit', t('Add Job Set'), array('class' => 'btn'))?>

	</form>

	<? } ?>

<? } ?>

<?=$h->getDashboardPaneFooterWrapper();?>


text:
@interface CMThirdFrameworkController ()<UITableViewDelegate,UITableViewDataSource>

@property (nonatomic, strong) NSArray *toolArray;

@end

@implementation CMThirdFrameworkController

- (void)viewDidLoad {
    [super viewDidLoad];

    //1.初始化数据
    [self initData];

    //2.创建UI
    [self initUI];
}

#pragma mark - 初始化数据
- (void)initData{
    self.toolArray = @[
                       @{@"name":@"ConstraintsLayout(约束布局)",@"classType":[MASExampleListViewController class]},
                       @{@"name":@"NetWork(网络请求)",@"classType":[GlobalTimelineViewController class]},
                       @{@"name":@"ImageCache(图片缓存)",@"classType":[MasterViewController class]},
                       @{@"name":@"ImageMultipleChoice(图片多选器)",@"classType":[CMAlbumImagesSampleController class]},
                       @{@"name":@"QRCode(二维码/条形码)",@"classType":[CMQRCodeSampleController class]},
                       @{@"name":@"Refresh(上拉/下拉刷新)",@"classType":[MJExampleViewController class]},
                       @{@"name":@"CyclePicture(无限轮播)",@"classType":[CMCyclePictureSampleController class]},
                       @{@"name":@"VerticalWaterFlow(垂直瀑布流)",@"classType":[CMWaterfallLayoutController class]},
                       @{@"name":@"RevealContorller(侧滑菜单控制器)",@"classType":[CMRevealSampleController class]},
                       @{@"name":@"TopSegumentView(顶部联动滑块视图)",@"classType":[CMTopSegumentViewSampleController class]},
                       @{@"name":@"CropPicture(裁剪图片)",@"classType":[CMCropPictureSampleController class]},
                       @{@"name":@"LaunchAd(广告载入页)",@"classType":[CMLaunchAdSampleController class]},
                       @{@"name":@"iCarousel(旋转木马效果)",@"classType":[CMICarouselSampleController class]},
                       @{@"name":@"UICountingLabel(数字Label)",@"classType":[CMCountLabelSampleController class]},
                       @{@"name":@"Chart(图表)",@"classType":[CMChartsTableViewController class]},
                       @{@"name":@"AudioVideo(音频/视频)",@"classType":[CMVideoPlayerSampleController class]}
                   ];

}

#pragma mark - 初始化UI
//创建UI
- (void)initUI{

    self.view.backgroundColor = [UIColor whiteColor];

    //1.创建TableView
    UITableView *tableView = [UITableView initWithFrame:self.view.bounds style:UITableViewStylePlain cellSeparatorStyle:UITableViewCellSeparatorStyleSingleLine separatorInset:UIEdgeInsetsMake(0, 0, 0, 0) dataSource:self delegate:self];

//    [tableView registerClass:[CMHeadView class] forHeaderFooterViewReuseIdentifier:@"CMHeadView"];

    tableView.tableHeaderView = [CMHeadView headView];

    [self.view addSubview:tableView];

}

#pragma mark - UITableViewDataSource
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return self.toolArray.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *ID = @"CMThirdFrameworkController";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }

    NSDictionary *dict = self.toolArray[indexPath.row];
    cell.textLabel.text = dict[@"name"];

    return cell;

}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{

    CMHeadView *headView = [[CMHeadView alloc] initWithReuseIdentifier:@"CMHeadView"];
    headView.titleStr = @"常用第三方框架选型";

    return headView;

}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSDictionary *dict = self.toolArray[indexPath.row];
    if (dict) {

        if ([dict[@"classType"] isEqual:[MBProgressHUD class]]) {
            [MBProgressHUD showSuccess:@"this is a test"];

        }else if([dict[@"classType"] isEqual:@""]){
            [MBProgressHUD showError:@"功能暂未完善"];

        }else if([dict[@"classType"] isEqual:SourceCode]){
            [MBProgressHUD showSuccess:@"请移步源码对应的类"];

        }else if ([dict[@"classType"] isEqual:[CMRevealSampleController class]]){
            CMRevealSampleController *Vc = [[CMRevealSampleController alloc] init];
            [self presentViewController:Vc animated:YES completion:nil];
        }else{
            UIViewController *Vc = [[dict[@"classType"] alloc] init];
            Vc.hidesBottomBarWhenPushed = YES;
            [self.navigationController pushViewController:Vc animated:YES];
        }
    }

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 35;
}

@end


text:
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
    <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" />
    <title>StandardAnalyzer Constructor (TextReader)</title>
    <xml>
    </xml>
    <link rel="stylesheet" type="text/css" href="MSDN.css" />

            Apache Lucene.Net 2.4.0 Class Library API

StandardAnalyzer Constructor (TextReader)

Builds an analyzer with the stop words from the given reader.

public StandardAnalyzer(
   TextReader stopwords
);

See Also

        StandardAnalyzer Class | Lucene.Net.Analysis.Standard Namespace | StandardAnalyzer Constructor Overload List | GetWordSet

Generated from assembly Lucene.Net [2.4.0.2]


text:
/******************************************************************************
 Hierarchy tools
*******************************************************************************/

'use strict';

var _ = require('underscore'),
    logger = require('../logger');

module.exports = function(options, instance, self) {
  var storage = self.storage;

  self.refreshChildrenCount = function(app_id, doc_id, done) {
    setTimeout(function() {
      storage.get(app_id, doc_id, function(document) {
        if (!document) {
          done && done();
          return;
        }
        storage.count_attributes(app_id, {
          parent: doc_id,
          archived: false,
          type__not: 'category'
        }, function(total) {
          storage.update(app_id, document, {
            children_count: total
          }, function(updated_doc) {
            if (updated_doc) {
              self.invalidateDocument(app_id, updated_doc);
              logger.info(app_id, 'refresh_children_count', updated_doc.get('id') + ': ' + total);
            }
            done && done();
          });
        });
      });
    }, 2000);
  }

  self.refreshUpdateTS = function(app_id, doc_id, now, user) {
    storage.get(app_id, doc_id, function(document) {
      if (!document) {
        return;
      }
      storage.update(app_id, document, {
        updated: now
      }, function(updated_doc) {
        if (updated_doc) {
          self.invalidateDocument(app_id, updated_doc);
          logger.info(app_id, 'refresh_updated_ts', updated_doc.get('id') + ': ' + now);
          if (user) {
            self.broadcastInfo(user, updated_doc);
          }
          if (updated_doc.get('parent')) {
            self.refreshUpdateTS(app_id, updated_doc.get('parent'), now, user);
          }
        }
      });
    });
  }

  self.refreshNotify = function(app_id, doc_id, user) {
    storage.get(app_id, doc_id, function(document) {
      if (!document) {
        return;
      }
      self.invalidateDocument(app_id, document);
      logger.info(app_id, 'refresh_notify', document.get('id'));
      if (user) {
        self.broadcastInfo(user, document);
      }
      if (document.get('parent')) {
        self.refreshNotify(app_id, document.get('parent'), user);
      }
    });
  }

}


text:
package header

import (
	"errors"
	"strings"
	"github.com/caa-dev-apps/cefmdd_v1/pkg/readers"
	"github.com/caa-dev-apps/cefmdd_v1/pkg/diag"
)

func (hds *CefHeaderData) kv_meta_entry(kv *readers.KeyVal) (err error) {
    //todo need to  add entry to current Meta{}
    diag.Todo("kv_meta_entry")
    return
}

func (hds *CefHeaderData) kv_meta_value_type(kv *readers.KeyVal) (err error) {
    //todo need to  add value_type to current Meta{}
    diag.Todo("kv_meta_value_type")
	return
}

func (hds *CefHeaderData) kv_meta(kv *readers.KeyVal) (err error) {

	switch {
	case strings.EqualFold("ENTRY", kv.Key) == true:
		err = hds.kv_meta_entry(kv)
	case strings.EqualFold("VALUE_TYPE", kv.Key) == true:
		err = hds.kv_meta_value_type(kv)
	default:
		return errors.New("META KEY: unknown")
	}

	return
}

// todo NEW for cef mdd_v1
func (hds *CefHeaderData) stx_meta(name *string) (err error) {
	//todo v1 hds.m_meta = Meta{}
	//todo v1 hds.m_meta.name = *name

	return
}

// todo NEW for cef mdd_v1
func (hds *CefHeaderData) etx_meta() (err error) {
	//todo v1 hds.m_data.metamap = append(hds.m_data.metamap, hds.m_meta)

	return
}


text:
package com.WazaBe.HoloEverywhere.app;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import com.WazaBe.HoloEverywhere.LayoutInflater;
import com.WazaBe.HoloEverywhere.util.Pair;

public class DialogFragment extends Fragment implements
		DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
	private static final String SAVED_BACK_STACK_ID = "android:backStackId";
	private static final String SAVED_CANCELABLE = "android:cancelable";
	private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState";
	private static final String SAVED_SHOWS_DIALOG = "android:showsDialog";

	private static final String SAVED_STYLE = "android:style";
	private static final String SAVED_THEME = "android:theme";
	public static final int STYLE_NO_FRAME = 2;
	public static final int STYLE_NO_INPUT = 3;
	public static final int STYLE_NO_TITLE = 1;
	public static final int STYLE_NORMAL = 0;

	protected final String classTag = getClass().getName() + "@!"
			+ Integer.toHexString(getClass().hashCode());
	int mBackStackId = -1;
	boolean mCancelable = true;
	Dialog mDialog;
	boolean mDismissed;

	boolean mShownByMe;
	boolean mShowsDialog = true;
	int mStyle = STYLE_NORMAL;
	int mTheme = 0;

	boolean mViewDestroyed;

	public void dismiss() {
		dismissInternal(false);
	}

	public void dismissAllowingStateLoss() {
		dismissInternal(true);
	}

	void dismissInternal(boolean allowStateLoss) {
		if (mDismissed) {
			return;
		}
		mDismissed = true;
		mShownByMe = false;
		if (mDialog != null) {
			mDialog.dismiss();
			mDialog = null;
		}
		mViewDestroyed = true;
		if (mBackStackId >= 0) {
			getFragmentManager().popBackStack(mBackStackId,
					FragmentManager.POP_BACK_STACK_INCLUSIVE);
			mBackStackId = -1;
		} else {
			FragmentTransaction ft = getFragmentManager().beginTransaction();
			ft.remove(this);
			if (allowStateLoss) {
				ft.commitAllowingStateLoss();
			} else {
				ft.commit();
			}
		}
	}

	public Dialog getDialog() {
		return mDialog;
	}

	@Override
	public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
		if (!mShowsDialog) {
			return super.getLayoutInflater(savedInstanceState);
		}
		mDialog = onCreateDialog(savedInstanceState);
		switch (mStyle) {
		case STYLE_NO_INPUT:
			mDialog.getWindow().addFlags(
					WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
							| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
		case STYLE_NO_FRAME:
		case STYLE_NO_TITLE:
			mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		}
		try {
			if (mDialog != null) {
				return LayoutInflater.from(mDialog.getContext());
			}
			return LayoutInflater.from(getSupportActivity());
		} catch (ClassCastException e) {
			return super.getLayoutInflater(savedInstanceState);
		}
	}

	public boolean getShowsDialog() {
		return mShowsDialog;
	}

	public int getTheme() {
		return mTheme;
	}

	public void hide() {
		hide(getSupportFragmentManager().beginTransaction());
	}

	public void hide(FragmentManager fm, FragmentTransaction ft) {
		Fragment fragment = (Fragment) fm.findFragmentByTag(classTag);
		if (fragment != null) {
			ft.remove(fragment);
		}
	}

	public void hide(FragmentTransaction ft) {
		hide(getSupportFragmentManager(), ft);
	}

	public boolean isCancelable() {
		return mCancelable;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		if (!mShowsDialog) {
			return;
		}
		View view = getView();
		if (view != null) {
			if (view.getParent() != null) {
				throw new IllegalStateException(
						"DialogFragment can not be attached to a container view");
			}
			mDialog.setContentView(view);
		}
		mDialog.setOwnerActivity(getActivity());
		mDialog.setCancelable(mCancelable);
		mDialog.setOnCancelListener(this);
		mDialog.setOnDismissListener(this);
		if (savedInstanceState != null) {
			Bundle dialogState = savedInstanceState
					.getBundle(SAVED_DIALOG_STATE_TAG);
			if (dialogState != null) {
				mDialog.onRestoreInstanceState(dialogState);
			}
		}
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		if (!mShownByMe) {
			mDismissed = false;
		}
	}

	@Override
	public void onCancel(DialogInterface dialog) {
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mShowsDialog = getContainerId() == 0;
		if (savedInstanceState != null) {
			mStyle = savedInstanceState.getInt(SAVED_STYLE, STYLE_NORMAL);
			mTheme = savedInstanceState.getInt(SAVED_THEME, 0);
			mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, true);
			mShowsDialog = savedInstanceState.getBoolean(SAVED_SHOWS_DIALOG,
					mShowsDialog);
			mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, -1);
		}
	}

	public Dialog onCreateDialog(Bundle savedInstanceState) {
		return new Dialog(getActivity(), getTheme());
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
		if (mDialog != null) {
			mViewDestroyed = true;
			mDialog.dismiss();
			mDialog = null;
		}
	}

	@Override
	public void onDetach() {
		super.onDetach();
		if (!mShownByMe && !mDismissed) {
			mDismissed = true;
		}
	}

	@Override
	public void onDismiss(DialogInterface dialog) {
		if (!mViewDestroyed) {
			dismissInternal(true);
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if (mDialog != null) {
			Bundle dialogState = mDialog.onSaveInstanceState();
			if (dialogState != null) {
				outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState);
			}
		}
		if (mStyle != STYLE_NORMAL) {
			outState.putInt(SAVED_STYLE, mStyle);
		}
		if (mTheme != 0) {
			outState.putInt(SAVED_THEME, mTheme);
		}
		if (!mCancelable) {
			outState.putBoolean(SAVED_CANCELABLE, mCancelable);
		}
		if (!mShowsDialog) {
			outState.putBoolean(SAVED_SHOWS_DIALOG, mShowsDialog);
		}
		if (mBackStackId != -1) {
			outState.putInt(SAVED_BACK_STACK_ID, mBackStackId);
		}
	}

	@Override
	public void onStart() {
		super.onStart();
		if (mDialog != null) {
			mViewDestroyed = false;
			mDialog.show();
		}
	}

	@Override
	public void onStop() {
		super.onStop();
		if (mDialog != null) {
			mDialog.hide();
		}
	}

	public Pair<FragmentTransaction, Integer> replace() {
		return replace(getSupportFragmentManager());
	}

	public Pair<FragmentTransaction, Integer> replace(FragmentManager fm) {
		return replace(fm, fm.beginTransaction());
	}

	public Pair<FragmentTransaction, Integer> replace(FragmentManager fm,
			FragmentTransaction ft) {
		hide(fm, ft);
		ft.addToBackStack(null);
		return show(ft);
	}

	public Pair<FragmentTransaction, Integer> replace(FragmentTransaction ft) {
		return replace(getSupportFragmentManager(), ft);
	}

	public void setCancelable(boolean cancelable) {
		mCancelable = cancelable;
		if (mDialog != null) {
			mDialog.setCancelable(cancelable);
		}
	}

	public void setShowsDialog(boolean showsDialog) {
		mShowsDialog = showsDialog;
	}

	public void setStyle(int style, int theme) {
		mStyle = style;
		if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) {
			mTheme = android.R.style.Theme_Panel;
		}
		if (theme != 0) {
			mTheme = theme;
		}
	}

	public Pair<FragmentTransaction, Integer> show() {
		return show(getSupportFragmentManager().beginTransaction());
	}

	@Deprecated
	public void show(FragmentManager manager, String tag) {
		mDismissed = false;
		mShownByMe = true;
		FragmentTransaction ft = manager.beginTransaction();
		ft.add(this, tag);
		ft.commit();
	}

	public Pair<FragmentTransaction, Integer> show(FragmentTransaction ft) {
		return Pair.create(ft, show(ft, classTag));
	}

	@Deprecated
	public int show(FragmentTransaction transaction, String tag) {
		mDismissed = false;
		mShownByMe = true;
		transaction.add(this, tag);
		mViewDestroyed = false;
		mBackStackId = transaction.commit();
		return mBackStackId;
	}
}


text:
package gatech.mmpm.tools;

import jargs.gnu.CmdLineParser;

import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import gatech.mmpm.tools.templates.TextTemplate;

import gatech.mmpm.tools.expressionparser.*;
import gatech.mmpm.tools.parseddomain.*;
import gatech.mmpm.tools.compiler.Builtin2JavaPackages;
import gatech.mmpm.tools.compiler.Builtin2Java;

import gatech.mmpm.ActionParameterType;

/**
 * Application that allows game developers to create the different
 * domain classes (IDomain, subclasses of Entity, etc.) of their
 * domains.
 * <p>
 * It receives the specification via an XML-file and construct the .java
 * files that should be included on the games and dynamically in the
 * AI engines.
 *
 * This class can be used as a stand alone application to generate
 * Java code, or programatically using its methods (specially
 * parseDomainElement() ) from other Java applications.
 *
 * @author Pedro Pablo Gomez Martin, based in some previous work of
 * Marco Antonio Gomez Martin, Jai Rad, Prafulla Mahindrakar and
 * Santi Onta�on.
 *
 * @date August, 2009
 */
public class DomainGenerator {

	/**
	 * Main program. You can consult the valid args executing
	 * the program or consulting the printUsage() code.
	 *
	 * @param args Program parameters.
	 *
	 * @note This method just calls to mainWrapper and
	 * returns it result to the underlying operative system.
	 */
	public static void main(String[] args) {

        System.exit(realMain(args));

	} // main

	//--------------------------------------------------------

	public DomainGenerator() {

		_generatedClassesNames = new LinkedList<String>();

		_generatedCode = new LinkedList<String>();

	} // constructor

	//--------------------------------------------------------

	// TODO: comentar!
	// It fills the Java code attributes.
	public boolean parseDomainElement(Element domainNode) {

		// If the name is changed, you should update the
		// main comment of the class.

		ParsedDomain parsedDomain;
		ParsedDomain nativeDomain;

		nativeDomain = getNativeDomain();
		if (nativeDomain == null)
			return false;

		parsedDomain = new ParsedDomain();
		try {
			parsedDomain.init(domainNode, nativeDomain);
			parsedDomain.process();
		}
		catch (ParseException e) {
			System.err.println(e.getMessage());
			return false;
		}

		// TODO: decide this depending on the parameters?
		// TODO: ���action base class name!!!
		generateEntitiesCode(parsedDomain, nativeDomain.getEntitySet().getPackageName(), "gatech.mmpm.Action");
		generateActionsCode(parsedDomain);
		generateMethodsCode(parsedDomain);
		generateIDomain(parsedDomain, domainNode);

		return true;

	} // parseDomainElement

	//--------------------------------------------------------
	//                   Protected methods
	//--------------------------------------------------------

	/**
	 * Builds a new ParsedDomain using the specification of the
	 * "native domain" (classes provided by MMPM) found in
	 * gatech.mmpm.tools.nativedomain.NativeDomain.xml. This
	 * file uses the same specification than the third-party
	 * game domains.
	 */
	protected ParsedDomain getNativeDomain() {

		ParsedDomain result;
		java.io.InputStream input = null;
		java.net.URI u = null;
		try {
			// Try in the path of this class
			u = getClass().getResource("/gatech/mmpm/tools/nativedomain/NativeDomain.xml").toURI();
			input = new java.io.FileInputStream(new java.io.File(u));
		} catch (Exception ex) {
			System.err.println("Native domain specification could not be founded (in " + u +")");
			return null;
		}

		SAXBuilder builder = new SAXBuilder();
		Document document;
		try {
			document = builder.build(input);
			Element root = document.getRootElement(); // <Domain>
			if (root == null) {
				System.err.println("Native domain has no root element (in " + u +")");
				return null;
			}

			result = new ParsedDomain();
			result.init(root, null);
			result.processAsNativeDomain();

			return result;

		} catch (Exception e) {
			System.err.println("Native domain could not be parsed (from " + u +")");
			e.printStackTrace();
			return null;
		}

	} // getNativeDomain

	//--------------------------------------------------------

	/**
	 * Parses the XML input file, and fill the object attributes
	 * with the resulting information.
	 *
	 * @param is Input stream where the XML can be reached.
	 *
	 * @return True if the XML could be parsed.
	 */
	protected boolean parseXML(java.io.InputStream is) {

		SAXBuilder builder = new SAXBuilder();
		Document document;
		try {
			document = builder.build(is);
			Element root = document.getRootElement(); // <Domain>
			if (root == null)
				return false;

			// TODO: parameters to choose which classes
			// should be generated?
			return parseDomainElement(root);

		} catch (JDOMException e) {
			e.printStackTrace();
			return false;
		} catch (java.io.IOException e) {
			e.printStackTrace();
			return false;
		}

	} // parseXML

	//--------------------------------------------------------

	protected boolean generateEntitiesCode(ParsedDomain domain,
	                                       String nativeEntityPackageName,
	                                       String nativeActionCompleteName) {

		List<ParsedEntity> entities;
		TextTemplate template;
		TextTemplate headerTemplate;
		TextTemplate getterAndSetterTemplate;
		TextTemplate stringSetterTemplate; // void set(String rhs)
		TextTemplate genericGetter;
		TextTemplate genericSetter;

		headerTemplate = getTemplate("Header");
		if (headerTemplate == null)
			return false;
		template = getTemplate("Entity.java");
		if (template == null)
			return false;
		getterAndSetterTemplate = getTemplate("EntityFeatureSetAndGet");
		if (getterAndSetterTemplate == null)
			return false;
		stringSetterTemplate = getTemplate("EntityFeatureSetString");
		if (stringSetterTemplate == null)
			return false;
		genericGetter = getTemplate("EntityFeatureGenericGetter");
		if (genericGetter == null)
			return false;
		genericSetter = getTemplate("EntityFeatureGenericSetter");
		if (genericSetter == null)
			return false;

		String entitiesPackage;
		String actionsPackage;
		ParsedEntitySet entitySet;
		entitiesPackage = domain.getEntitySet().getPackageName();
		entitySet = domain.getEntitySet();

		actionsPackage = domain.getActionSet().getPackageName();

		entities = entitySet.getEntities();

		for (ParsedEntity e:entities) {
			if (e.isNative())
				continue;

			String entityClassName;
			String fullEntityClassName;
			String entitySuperclassName;
			List<ParsedAction> actions = e.getActions();
			String actionsImport;

			entityClassName = e.getName();
			if (entitiesPackage != null)
				fullEntityClassName = entitiesPackage + "." + entityClassName;
			else
				fullEntityClassName = entityClassName;

			if (entitySet.getEntity(e.getSuperClassName()).isNative())
				entitySuperclassName = nativeEntityPackageName + "." + e.getSuperClassName();
			else
				entitySuperclassName = /*entitiesPackage + "." + */ e.getSuperClassName();

			template.reset();
			template.replace("<<<Disclaimer>>>", headerTemplate.getResult());

			template.replace("<<<optional package name>>>", entitySet.getJavaPackageDeclaration());

			template.replace("<<<ActionBaseClass>>>", nativeActionCompleteName);

			template.replace("<<<entityName>>>", entityClassName);
			template.replace("<<<superclass>>>", entitySuperclassName);

			// TODO: to ActionSet
			if (actions.size() == 0) {
				actionsImport = "";
			}
			else {
				// We will create a Set with all the actions used in
				// this entity. The set is needed to remove repeated
				// actions (with different binded parameters).
				java.util.Set<String> actionsNamesSet;
				actionsNamesSet = new java.util.TreeSet<String>();
				for (ParsedAction a:actions) {
					actionsNamesSet.add(a.getName());
				} // for actions

				StringBuffer sbActionsImport = new StringBuffer();
				String initImport;
				if (actionsPackage.length() != 0)
					initImport = "import " + actionsPackage + ".";
				else
					initImport = "import ";

				for (String an:actionsNamesSet) {
					sbActionsImport.append(initImport);
					sbActionsImport.append(an);
					sbActionsImport.append(";\n");
				} // for actions
				actionsImport = sbActionsImport.toString();
			} // if-else actions.size() == 0

			template.replace("<<<optional import actions>>>", actionsImport);

//			template.replace("<<<entityName>>>", entityClassName);
			// It was done previously...

			template.replace("<<<Declared fields>>>", e.getFeaturesJavaDeclaration());

			template.replace("<<<copy declared features>>>", e.getJavaCopyDeclaredFeatures());
			template.replace("<<<default values assignments>>>", e.getJavaFeaturesDefaultValuesAssignments());

			String shortNameStr;
			if (e.getShortName() == '\0')
				shortNameStr = "\\0";
			else
				shortNameStr = "" + e.getShortName();
			template.replace("<<<shortName>>>", shortNameStr);

			StringBuffer sbGetterAndSetter = new StringBuffer();
			StringBuffer sbGenericGetter = new StringBuffer();
			StringBuffer sbGenericSetter = new StringBuffer();

			for (ParsedFeature f:e.getFeatures()) {
				if (f.isInherited())
					continue;

				getterAndSetterTemplate.replace("<<<featureName>>>", f.getName());
				getterAndSetterTemplate.replace("<<<dataType>>>", f.getDatatype());
				String casedFeatureName;
				casedFeatureName = ("" + f.getName().charAt(0)).toUpperCase() +
				                   f.getName().substring(1);
				getterAndSetterTemplate.replace("<<<casedFeatureName>>>", casedFeatureName);
				sbGetterAndSetter.append(getterAndSetterTemplate.getResult());
				getterAndSetterTemplate.reset();

				if (f.getDatatype().compareTo("String") != 0) {
					stringSetterTemplate.replace("<<<casedFeatureName>>>", casedFeatureName);
					stringSetterTemplate.replace("<<<featureName>>>", f.getName());
					String parser;
					String postParser = ")";
					if (f.getDatatype().compareToIgnoreCase("boolean") == 0)
						parser = "Boolean.parseBoolean(";
					else if (f.getDatatype().compareToIgnoreCase("char") == 0) {
						parser = "";
						postParser = ".charAt(0)";
					}
					else if (f.getDatatype().compareToIgnoreCase("int") == 0)
						parser = "Integer.parseInt(";
					else if (f.getDatatype().compareToIgnoreCase("long") == 0)
						parser = "Long.parseLong(";
					else if (f.getDatatype().compareToIgnoreCase("float") == 0)
						parser = "Float.parseFloat(";
					else if (f.getDatatype().compareToIgnoreCase("double") == 0)
						parser = "Double.parseDouble(";
					else {
						System.err.println("Unknown datatype!? (" + f.getDatatype() + ")");
						return false;
					}
					stringSetterTemplate.replace("<<<parser>>>", parser);
					stringSetterTemplate.replace("<<<postParser>>>", postParser);

					sbGetterAndSetter.append(stringSetterTemplate.getResult());
					stringSetterTemplate.reset();
				} // if datatype != "String"

				// generic getter
				genericGetter.replace("<<<featureName>>>", f.getName());
				genericGetter.replace("<<<casedFeatureName>>>", casedFeatureName);
				sbGenericGetter.append(genericGetter.getResult());
				genericGetter.reset();

				// generic setter
				genericSetter.replace("<<<featureName>>>", f.getName());
				genericSetter.replace("<<<casedFeatureName>>>", casedFeatureName);
				sbGenericSetter.append(genericSetter.getResult());
				genericSetter.reset();

			}

			template.replace("<<<getters and setters>>>", sbGetterAndSetter.toString());

			template.replace("<<<initialize list of features>>>", e.getJavaFeatureListInitialization());

			template.replace("<<<genericGetter>>>", sbGenericGetter.toString());

			template.replace("<<<genericSetter>>>", sbGenericSetter.toString());

			template.replace("<<<isActive>>>", e.isActive()?"true":"false");

			StringBuffer sbActions = new StringBuffer();
			if ((actions != null) && actions.size() > 0)
				sbActions.append("\t\tAction a;\n");
			for (ParsedAction a:actions) {
				sbActions.append("\t\ta = new " + a.getName() + "(null, null);\n");
				for (ParsedActionParameter p:a.getParameters()) {
					sbActions.append("\t\ta.setParameterValue(\""+p.getName() + "\", \"" + p.getValue() + "\");\n");
				}
				sbActions.append("\t\t_listOfActions.add(a);\n\n");
			} // for actions

			template.replace("<<<initialize list of actions>>>", sbActions.toString());

			_generatedClassesNames.add(fullEntityClassName);
			_generatedCode.add(template.getResult());

		} // for entities

		return true;

	} // generateEntitiesCode

	//--------------------------------------------------------

	protected boolean generateActionsCode(ParsedDomain domain) {

		List<ParsedAction> actions;
		TextTemplate template;
		TextTemplate headerTemplate;
		TextTemplate getterAndSetterTemplate;
		TextTemplate stringGetterTemplate; // String getStringName()
		TextTemplate stringSetterTemplate; // void set(String rhs)
		TextTemplate genericGetter;
		TextTemplate genericStringGetter;
		TextTemplate genericSetter;
		TextTemplate getContext;
		TextTemplate onCondition;

		headerTemplate = getTemplate("Header");
		if (headerTemplate == null)
			return false;
		template = getTemplate("Action.java");
		if (template == null)
			return false;
		getterAndSetterTemplate = getTemplate("ActionParameterSetAndGet");
		if (getterAndSetterTemplate == null)
			return false;
		stringSetterTemplate = getTemplate("ActionParameterSetString");
		if (stringSetterTemplate == null)
			return false;
		stringGetterTemplate = getTemplate("ActionParameterGetString");
		if (stringSetterTemplate == null)
			return false;
		genericGetter = getTemplate("ActionParameterGenericGetter");
		if (genericGetter == null)
			return false;
		genericStringGetter = getTemplate("ActionParameterGenericStringGetter");
		if (genericStringGetter == null)
			return false;
		genericSetter = getTemplate("ActionParameterGenericSetter");
		if (genericSetter == null)
			return false;
		getContext = getTemplate("ActionGetContext");
		if (getContext == null)
			return false;
		onCondition = getTemplate("ActionOnCondition");
		if (onCondition == null)
			return false;

		if (getContext == null)
			return false;

		String actionsPackage;
		ParsedActionSet actionSet;

		actionSet = domain.getActionSet();

		actionsPackage = actionSet.getPackageName();

		actions = actionSet.getAction();

		SymbolTable symbolTable = getSymbolTable(domain.getSensorSet(),
                domain.getGoalSet());

		for (ParsedAction a:actions) {

			String actionClassName;
			String fullActionClassName;

			actionClassName = a.getName();
			if (actionsPackage != null)
				fullActionClassName = actionsPackage + "." + actionClassName;
			else
				fullActionClassName = actionClassName;

			template.reset();
			template.replace("<<<Disclaimer>>>", headerTemplate.getResult());

			template.replace("<<<optional package name>>>", actionSet.getJavaPackageDeclaration());

			template.replace("<<<actionName>>>", actionClassName);

			template.replace("<<<Declared fields>>>", a.getParametersJavaDeclaration());

			template.replace("<<<copy declared parameters>>>", a.getJavaCopyDeclaredParameters());

			StringBuffer sbGetterAndSetter = new StringBuffer();
			StringBuffer sbGenericGetter = new StringBuffer();
			StringBuffer sbGenericStringGetter = new StringBuffer();
			StringBuffer sbGenericSetter = new StringBuffer();
			StringBuffer sbGetContext = new StringBuffer();

			for (ParsedActionParameter p:a.getParameters()) {

				getterAndSetterTemplate.replace("<<<parameterName>>>", p.getName());
				getterAndSetterTemplate.replace("<<<dataType>>>", p.getType().getJavaTypeDeclaration());
				String casedParameterName;
				casedParameterName = ("" + p.getName().charAt(0)).toUpperCase() +
				                      p.getName().substring(1);
				getterAndSetterTemplate.replace("<<<casedParameterName>>>", casedParameterName);
				sbGetterAndSetter.append(getterAndSetterTemplate.getResult());
				getterAndSetterTemplate.reset();

				if (p.getType().getJavaTypeDeclaration().compareTo("String") != 0) {

					stringGetterTemplate.replace("<<<casedParameterName>>>", casedParameterName);
					stringGetterTemplate.replace("<<<parameterName>>>", p.getName());
					stringGetterTemplate.replace("<<<parameterType>>>", p.getType().toString());

					stringSetterTemplate.replace("<<<casedParameterName>>>", casedParameterName);
					stringSetterTemplate.replace("<<<parameterName>>>", p.getName());

					stringSetterTemplate.replace("<<<parameterTypeClass>>>",
					                             p.getType().getJavaTypeDeclaration());
					stringSetterTemplate.replace("<<<parameterType>>>", p.getType().toString());

					sbGetterAndSetter.append(stringGetterTemplate.getResult());
					stringGetterTemplate.reset();

					sbGetterAndSetter.append(stringSetterTemplate.getResult());
					stringSetterTemplate.reset();

				} // if datatype != "String"

				// generic getter
				genericGetter.replace("<<<parameterName>>>", p.getName());
				genericGetter.replace("<<<casedParameterName>>>", casedParameterName);
				sbGenericGetter.append(genericGetter.getResult());
				genericGetter.reset();

				// generic string getter
				genericStringGetter.replace("<<<parameterName>>>", p.getName());
				genericStringGetter.replace("<<<casedParameterName>>>", casedParameterName);
				// If the current parameter is a String, then the
				// method to get the parameter value as string has the
				// common getter name of get<Name>().
				// But if the parameter has any other value, then
				// the getter get<Name>() will return the native type
				// and the getString<Name>() method should be used.
				if (p.getType().getJavaTypeDeclaration().compareTo("String") != 0)
					genericStringGetter.replace("<<<optionalString>>>", "String");
				else
					genericStringGetter.replace("<<<optionalString>>>", "");

				sbGenericStringGetter.append(genericStringGetter.getResult());
				genericStringGetter.reset();

				// generic setter
				genericSetter.replace("<<<parameterName>>>", p.getName());
				genericSetter.replace("<<<casedParameterName>>>", casedParameterName);
				sbGenericSetter.append(genericSetter.getResult());
				genericSetter.reset();

				// getContext
				getContext.replace("<<<parameterName>>>", p.getName());
				sbGetContext.append(getContext.getResult());
				getContext.reset();

			} // for each action parameter

			template.replace("<<<getters and setters>>>", sbGetterAndSetter.toString());

			template.replace("<<<initialize list of parameters>>>", a.getJavaParameterListInitialization());

			template.replace("<<<genericGetter>>>", sbGenericGetter.toString());

			template.replace("<<<genericSetter>>>", sbGenericSetter.toString());

			template.replace("<<<genericStringGetter>>>", sbGenericStringGetter.toString());

			template.replace("<<<getContext>>>", sbGetContext.toString());

			// Conditions.
			Builtin2JavaPackages packages;
			packages = new Builtin2JavaPackages(domain);
			ExpressionNode expression;

			// We must add to the symbol table the parameters
			SymbolTable currentSymbolTable;
			currentSymbolTable = symbolTable.clone();
			for (ParsedActionParameter p:a.getParameters()) {
				if (symbolTable.getEntry(p.getName()) != null) {
					System.err.println("Invalid (duplicated) parameter name '" +
					                   p.getName() + "' in method '" +
					                   a.getName() + "'.");
					return false;
				}
				SymbolTableEntry e;

				e = new SymbolTableEntry(SymbolTable.EntryType.PARAMETER,
				                         p.getName(), p.getType());
				currentSymbolTable.addEntry(e);
			} // for (parameters)

			if (!generateConditionCode(a.getPreCondition(), "<<<preCondition>>>",
			                           "gatech.mmpm.Action._preCondition",
			                           currentSymbolTable, packages, template,domain))
				continue;

			if (!generateConditionCode(a.getSuccessCondition(), "<<<successCondition>>>",
                    "gatech.mmpm.Action._successCondition",
                    currentSymbolTable, packages, template,domain))
				continue;

			if (!generateConditionCode(a.getPreFailureCondition(), "<<<preFailureCondition>>>",
                    "gatech.mmpm.Action._preFailureCondition",
                    currentSymbolTable, packages, template,domain))
				continue;

			if (!generateConditionCode(a.getFailureCondition(), "<<<failureCondition>>>",
                    "gatech.mmpm.Action._failureCondition",
                    currentSymbolTable, packages, template,domain))
				continue;

			if (!generateConditionCode(a.getValidCondition(), "<<<validCondition>>>",
                    "gatech.mmpm.Action._validCondition",
                    currentSymbolTable, packages, template,domain))
				continue;

			if (!generateConditionCode(a.getPostCondition(), "<<<postCondition>>>",
                    "gatech.mmpm.Action._postCondition",
                    currentSymbolTable, packages, template,domain))
				continue;

			// -----------------
			// OnXXXXCondition
			// -----------------

			String onActionCode;
			onActionCode = generateOnConditionCode(a, a.getOnPreCondition(), "Pre",
			                                       currentSymbolTable, packages,
			                                       onCondition, domain);
			if (onActionCode == null)
				continue;
			template.replace("<<<onPreCondition>>>", onActionCode);

			onActionCode = generateOnConditionCode(a, a.getOnPostCondition(), "Post",
			                                       currentSymbolTable, packages,
			                                       onCondition, domain);
			if (onActionCode == null)
				continue;
			template.replace("<<<onPostCondition>>>", onActionCode);

			onActionCode = generateOnConditionCode(a, a.getOnPreFailureCondition(), "PreFailure",
			                                       currentSymbolTable, packages,
			                                       onCondition, domain);
			if (onActionCode == null)
				continue;
			template.replace("<<<onPreFailureCondition>>>", onActionCode);

			onActionCode = generateOnConditionCode(a, a.getOnFailureCondition(), "Failure",
			                                       currentSymbolTable, packages,
			                                       onCondition, domain);
			if (onActionCode == null)
				continue;
			template.replace("<<<onFailureCondition>>>", onActionCode);

			onActionCode = generateOnConditionCode(a, a.getOnSuccessCondition(), "Success",
			                                       currentSymbolTable, packages,
			                                       onCondition, domain);
			if (onActionCode == null)
				continue;
			template.replace("<<<onSuccessCondition>>>", onActionCode);

			onActionCode = generateOnConditionCode(a, a.getOnValidCondition(), "Valid",
			                                       currentSymbolTable, packages,
			                                       onCondition, domain);
			if (onActionCode == null)
				continue;
			template.replace("<<<onValidCondition>>>", onActionCode);

			template.replace("<<<optional sensor imports>>>", packages.getImportLines());

			_generatedClassesNames.add(fullActionClassName);
			_generatedCode.add(template.getResult());

		} // for actions

		return true;

	} // generateActionsCode

	//--------------------------------------------------------

	/**
	 * Generate the java classes for the sensors and goals of
	 * the domain.
	 *
	 * @param domain Domain which sensors and goals must be
	 * generated.
	 */
	protected boolean generateMethodsCode(ParsedDomain domain) {

		// Template initialization
		TextTemplate template;
		TextTemplate headerTemplate;
		TextTemplate backendTemplate;

		headerTemplate = getTemplate("Header");
		if (headerTemplate == null)
			return false;
		template = getTemplate("Sensor.java");
		if (template == null)
			return false;
		backendTemplate = getTemplate("SensorBackEnd.java");

		SymbolTable symbolTable = getSymbolTable(domain.getSensorSet(),
		                                         domain.getGoalSet());

		if (!generateMethodsCode(domain, domain.getSensorSet(), symbolTable,
		                         template, headerTemplate, backendTemplate))
			return false;

		if (!generateMethodsCode(domain, domain.getGoalSet(), symbolTable,
		                         template, headerTemplate, backendTemplate))
			return false;

		return true;

	} // generateMethodsCode

	//--------------------------------------------------------

	protected boolean generateIDomain(ParsedDomain domain, Element domainNode) {

		// We will use the tool developed by Marco Antonio
		// using XSLT.

		// The tool to generate the IDomain subclass for the
		// current game uses XSLT and the JRE XML classes.
		// We must provide it the XML with the domain, but we have
		// processed it yet using jdom.
		// As far as I know, the solution is to serialize
		// back the jdom Element to XML, and provide it
		// to the XSLT tool.
		org.jdom.output.XMLOutputter xmlWriter;
		xmlWriter = new org.jdom.output.XMLOutputter();
		java.io.StringWriter outputString;
		outputString = new java.io.StringWriter();
		try {
			xmlWriter.output(domainNode, outputString);
		}
		catch (java.io.IOException e) {
			System.err.println(e.getMessage());
			return false;
		}

		IDomainGenerator dg = new IDomainGenerator();
		java.io.StringReader stringReader;
		stringReader = new java.io.StringReader(outputString.toString());

		java.io.StringWriter stringWriter;
		stringWriter = new java.io.StringWriter();

		dg.run(stringReader, stringWriter);

		String completeClassName;
		if (domain.getPackageName().isEmpty())
			completeClassName = domain.getClassName();
		else
			completeClassName = domain.getPackageName() + "." + domain.getClassName();

		_generatedClassesNames.add(completeClassName);
		_generatedCode.add(stringWriter.toString());

		return true;

	} // generateIDomain

	//--------------------------------------------------------

	protected ExpressionNode getBuiltInExpression(ParsedMethod m,
			SymbolTable symbolTable) {

		// We must add to the symbol table the parameters
		SymbolTable currentSymbolTable;
		currentSymbolTable = symbolTable.clone();
		for (ParsedActionParameter p:m.getParameters()) {
			if (symbolTable.getEntry(p.getName()) != null) {
				System.err.println("Invalid (duplicated) parameter name '" +
				                   p.getName() + "' in method '" +
				                   m.getName() + "'.");
				return null;
			}
			SymbolTableEntry e;

			e = new SymbolTableEntry(SymbolTable.EntryType.PARAMETER,
			                         p.getName(), p.getType());
			currentSymbolTable.addEntry(e);
		} // for (parameters)

		ExpressionNode expression;

		expression = ExpressionParser.parse(m.getCode(), currentSymbolTable);

		return expression;

	} // getBuiltInExpression

	//--------------------------------------------------------

	/**
	 * Generate the java classes for the sensors and goals of
	 * the domain.
	 *
	 * @param domain Domain which sensors and goals must be
	 * generated.
	 */
	protected boolean generateMethodsCode(ParsedDomain domain,
                                          ParsedMethodSet methods,
	                                      SymbolTable symbolTable,
	                                      TextTemplate template,
	                                      TextTemplate headerTemplate,
	                                      TextTemplate backendTemplate) {

		String methodsPackage;
		methodsPackage = methods.getPackageName();

		for (ParsedMethod m:methods.getMethods()) {

			if (m.isNative())
				continue;

			template.reset();
			template.replace("<<<Disclaimer>>>", headerTemplate.getResult());

			String methodClassName;
			String fullMethodClassName;

			methodClassName = m.getName();
			if (methodsPackage != null) {
				fullMethodClassName = methodsPackage + "." + methodClassName;
			}
			else
				fullMethodClassName = methodClassName;

			if (methodsPackage != null) {
				template.replace("<<<optional package name>>>",
				                 "package " + methodsPackage + ";");
			}
			else {
				template.replace("<<<optional package name>>>", "");
			}

			template.replace("<<<sensorName>>>", methodClassName);

			template.replace("<<<SensorType>>>", m.getReturnedType().toString());

			if (m.getLanguage() != null) {
				if (m.getLanguage().compareToIgnoreCase("java") == 0) {
					template.replace("<<<optional backend sensor>>>", "");
					template.replace("<<<evaluate code>>>", m.getCode());
					template.replace("<<<optional sensor imports>>>", "");
				}
				else {
					throw new RuntimeException("Invalid language (" + m.getLanguage() + ")");
				}
			} // if (m.getLanguage() != null)
			else {
				// We have a sensor specified with the
				// built-in language.
				ExpressionNode expression;
				expression = getBuiltInExpression(m, symbolTable);

				backendTemplate.reset();
				backendTemplate.replace("<<<backendSensor>>>", Builtin2Java.compile(expression, domain));
				template.replace("<<<optional backend sensor>>>", backendTemplate.getResult());

				template.replace("<<<evaluate code>>>", "return _backend.evaluate(cycle, gs, player, parameters);");

				Builtin2JavaPackages b2jp;
				b2jp = new Builtin2JavaPackages(domain);
				expression.accept(b2jp);
				template.replace("<<<optional sensor imports>>>", b2jp.getImportLines());
			} // if-else (m.getLanguage() != null)

			String param = "";
			Iterator<ParsedActionParameter> it = m.getParameters().iterator();
			ParsedActionParameter pap;
			while(it.hasNext()) {
				pap = it.next();
				param = param +
				"_listOfNeededParameters.add(new Pair<String,ActionParameterType>(\"" +
				pap.getName() + "\", ActionParameterType." + pap.getType() + "));\n\t\t";
			}
			template.replace("<<<needed parameters>>>", param);

			// TODO: internalEquivalents!!!!!!!!

			_generatedClassesNames.add(fullMethodClassName);
			_generatedCode.add(template.getResult());

		} // for (methods)

		return true;

	} // generateMethodsCode

	//--------------------------------------------------------

	/**
	 * Very specific method used in generateActionsCode() to avoid
	 * some code repetition. This method is invoked to
	 * generate the conditions code.
	 */
	protected boolean generateConditionCode(String strCondition,
	                                        String mark, String defaultValue,
	                                        SymbolTable currentSymbolTable, Builtin2JavaPackages packages,
	                                        TextTemplate template, ParsedDomain domain) {

		ExpressionNode expression;
		if (strCondition != null) {
			try {
				expression = ExpressionParser.parse(strCondition, currentSymbolTable);
			}
			catch (Exception e) {
				System.err.println("Error parsing condition expression: " + strCondition);
				return false;
			}
			expression.accept(packages);
			template.replace(mark, Builtin2Java.compile(expression, domain));
		}
		else {
			// Action has the same condition than the
			// parent.
			template.replace(mark, defaultValue);
		}
		return true;

	}

	//--------------------------------------------------------

	/**
	 * Very specific method used in generateActionsCode() to avoid
	 * some code repetition. This method is invoked to
	 * generate the onXXXCondition code.
	 */
	protected String generateOnConditionCode(ParsedAction a, String strCondition, String condType,
	                                         SymbolTable currentSymbolTable, Builtin2JavaPackages packages,
	                                         TextTemplate template, ParsedDomain domain) {

		ExpressionNode expression;

		if (strCondition != null) {
			try {
				expression = ExpressionParser.parse(strCondition, currentSymbolTable);
			}
			catch (Exception e) {
				e.printStackTrace(); // TODO: remove this!
				return null;
			}
			template.reset();
			template.replace("<<<CondType>>>", condType);
			if (!(expression instanceof AssignmentNode)) {
				System.err.println("Non-assignment expression in on " + condType + "Condition " + strCondition + "\n");
				return null;
			}
			AssignmentNode assignment;
			assignment = (AssignmentNode) expression;

			template.replace("<<<targetValue>>>", assignment.getIdentifier());
			template.replace("<<<Value>>>", Builtin2Java.compile(assignment.getRHS(), domain));

			String identifierType;
			ParsedActionParameter identifier;
			identifier = a.getParameter(assignment.getIdentifier());
			if (identifier == null) {
				System.err.println(assignment.getIdentifier() + " is not a valid parameter for " + a.getName() + " action.");
				return null;
			}
			identifierType = identifier.getType().getJavaTypeDeclaration();
			template.replace("<<<IdentifierType>>>", identifierType);

			assignment.getRHS().accept(packages);
			return template.getResult();
		}
		else {
			return "";
		}

	} // generateOnConditionCode

	/**
	 * Save all the files in the object attributes to files
	 * in the specified directory.
	 *
	 * @param path Path of the output files.
	 * @throws java.io.IOException if some thing was wrong.
	 */
	protected void saveClassesToFiles(String path) throws java.io.IOException {

		java.util.Iterator<String> classNameIt, codeIt;

		classNameIt = _generatedClassesNames.iterator();
		codeIt = _generatedCode.iterator();

		while (classNameIt.hasNext() && codeIt.hasNext()) {
			String className = classNameIt.next();
			String code = codeIt.next();

			// className is in the form pack1.subpack2.classname
			// and we must convert it to pack1/subpack2/classname.java.
			String fileName = className.replace('.', java.io.File.separatorChar);

			if (path.endsWith("/") || path.endsWith("\\")) {
				fileName = path + fileName + ".java";
			}
			else
				fileName = path + java.io.File.separator + fileName + ".java";

			// Create the directories if they don't exist.
			java.io.File f = new java.io.File(fileName).getParentFile();
			f.mkdirs();

			// Now, we will create the file. Exceptions will not be
			// managed (just raised up).
			java.io.FileWriter fileWriter;
			fileWriter = new java.io.FileWriter(fileName);
			fileWriter.write(code);
			fileWriter.close();

		}

		if (classNameIt.hasNext() || codeIt.hasNext())
			// This should not happen!
			throw new RuntimeException("Internal error in DomainGenerator");

	} // saveToFiles

	//--------------------------------------------------------

	public static void printUsage() {
		// TODO:
		// programa -o <ruta salida> [fichero.xml]
		// -e entidades? -d dominio? -a acciones? -s sensores?...
		/*
		System.out.println("Trainer: uses a learning engine to train (create) a ME.");
		System.out.println();
		System.out.println("Usage: Learner -t trainerClass -g gameDomainClass -D attr=value ...");
		System.out.println();
		System.out.println("\t-t|--trainer: specify the Java class that contains the");
		System.out.println("\t              ME trainer. It must implements the ");
		System.out.println("\t              gatech.mmpm.learningengine.IMETrainer interface.");
		System.out.println();
		System.out.println("\t-g|--game:    specify the java class that contains the information");
		System.out.println("\t              about the game. It must implements the");
		System.out.println("\t              gatech.mmpm.IDomain interface.");
		System.out.println("\t-D name=value: specify an option to be sent to the trainer.");
		System.out.println("\t              It's up to it to understand this attr, value)");
		System.out.println("\t              pair.");
		System.out.println("\t-i|--input file:  specify the file name where traces will be read of.");
		System.out.println("\t                  If no one is specified, standard input will be used.");
		System.out.println("\t-o|--output file: specify the file name where write the ME. If no one");
		System.out.println("\t                  is specified, standard output will be used.");
		System.out.println();
		System.out.println("Standard input will be the source of the traces using a");
		System.out.println("specific XML format. Standard output will be the target for");
		System.out.println("the new created ME.");
		System.out.println();
		System.out.println("The program return 0 if the ME was correctly generated and");
		System.out.println("a different value in other case. Under this situation, ");
		System.out.println("standard output could have received some output that will be");
		System.out.println("invalid and should be discarded.");
		System.out.println();
		System.out.println("Notes:");
		System.out.println("\t- Traces MUST have been generated by the game which");
		System.out.println("\t  is modeled by the game domain (-d option)");
		*/
	} // printUsage

	//--------------------------------------------------------

	/**
	 * Builds a symbol table for the expression parser adding
	 * the methods of two methods set. The first one will be
	 * the sensors set, and the second one will be the goals set.
	 *
	 * The symbol table is also populated with the "global
	 * variables" and "generic parameters" that all actions
	 * have.
	 *
	 * @param sensorSet Sensor set of the domain which declarations
	 * will be added to the symbol table.
	 * @param goalSet Goal set of the domain which declarations
	 * will be added to the symbol table.
	 *
	 * @return Symbol table. null is returned if any problem occurs
	 * (for example, a sensor with the name of a generic parameter).
	 * In that case, System.err receives an explanation (this is
	 * not too clean, I know...)
	 */
	protected static SymbolTable getSymbolTable(ParsedMethodSet sensorSet,
	                                            ParsedMethodSet goalSet) {

		SymbolTable st = new SymbolTable();
		// We add the methods in the sensor set...
		for (ParsedMethod m:sensorSet.getMethods()) {
			List<SymbolTableEntry> parameters;
			parameters = new java.util.LinkedList<SymbolTableEntry>();
			for (ParsedActionParameter p:m.getParameters()) {
				SymbolTableEntry e;
				e = new SymbolTableEntry(SymbolTable.EntryType.PARAMETER, p.getName(), p.getType());
				parameters.add(e);
			}
			SymbolTableMethodEntry methodEntry;
			methodEntry = new SymbolTableMethodEntry(m.getName(), m.getReturnedType(), parameters);
			st.addEntry(methodEntry);
		}

		// ... and now in the goal set.
		for (ParsedMethod m:goalSet.getMethods()) {
			List<SymbolTableEntry> parameters;
			parameters = new java.util.LinkedList<SymbolTableEntry>();
			for (ParsedActionParameter p:m.getParameters()) {
				SymbolTableEntry e;
				e = new SymbolTableEntry(SymbolTable.EntryType.PARAMETER, p.getName(), p.getType());
				parameters.add(e);
			}
			SymbolTableMethodEntry methodEntry;
			methodEntry = new SymbolTableMethodEntry(m.getName(), m.getReturnedType(), parameters);
			st.addEntry(methodEntry);
		}

		// Add into the symbol table the "global variables".
		if (st.getEntry("cycle") != null) {
			System.err.println("cycle method name is not allowed.");
			return null;
		}
		if (st.getEntry("player") != null) {
			System.err.println("player method name is not allowed.");
			return null;
		}

		SymbolTableEntry e;
		e = new SymbolTableEntry(SymbolTable.EntryType.GLOBAL_VAR,
		                         "player", ActionParameterType.PLAYER);
		st.addEntry(e);
		e = new SymbolTableEntry(SymbolTable.EntryType.GLOBAL_VAR,
                "cycle", ActionParameterType.INTEGER);
		st.addEntry(e);

		// Add into the symbol table the "generic parameters" that
		// all actions will have.
		if (st.getEntry("entityID") != null) {
			System.err.println("entityID method name is not allowed.");
			return null;
		}
		if (st.getEntry("playerID") != null) {
			System.err.println("actor method name is not allowed.");
			return null;
		}
		e = new SymbolTableEntry(SymbolTable.EntryType.PARAMETER,
		                         "entityID", ActionParameterType.STRING);
		st.addEntry(e);
		e = new SymbolTableEntry(SymbolTable.EntryType.PARAMETER,
                "playerID", ActionParameterType.PLAYER);
		st.addEntry(e);
		// ��st.addEntry(e) for both of them??

		return st;

	} // getSymbolTable

	//--------------------------------------------------------

	/**
	 * Main program. You can consult the valid args executing
	 * the program or consulting the printUsage() code.
	 *
	 * @param args Program parameters.
	 *
	 * @return 0 if it works, and a different value in other
	 * case. This value should be send back to the operative system.
	 */
	protected static int realMain(String[] args) {

		CmdLineParser parser = new CmdLineParser();

		CmdLineParser.Option helpOpt = parser.addBooleanOption('h', "help");
		CmdLineParser.Option outputOpt = parser.addStringOption('o', "output");

		try {
			parser.parse(args);
		} catch (CmdLineParser.OptionException e) {
			System.err.println(e.getMessage());
			printUsage();
			System.exit(1);
		}

		boolean help = (Boolean)parser.getOptionValue(helpOpt, false);
		String outputPath = (String)parser.getOptionValue(outputOpt);

		if ((help) || (outputPath == null)) {
			printUsage();
			System.exit(0);
		}

		java.io.File file = new java.io.File(outputPath);
		if (!file.exists() || !file.isDirectory() || !file.canWrite()) {
	    	System.err.println("The specified path does not exists " +
	    	                   "or cannot be written.");
	    }

		String[] remainingOpts = parser.getRemainingArgs();

		if (remainingOpts.length > 1) {
			printUsage();
			System.exit(1);
        }

		String inputFileName = null;
		java.io.InputStream inStream;

		if (remainingOpts.length > 0) {
			inputFileName = remainingOpts[0];
		}

		if (inputFileName != null) {
			try {
				inStream = new java.io.FileInputStream(inputFileName);
			} catch (java.io.IOException ex) {
				System.err.println(inputFileName + " does not exists or could not be opened.");
				return 1;
			}
		}
		else
			inStream = System.in;

		DomainGenerator dg = new DomainGenerator();

		if (!dg.parseXML(inStream))
			return 1;

		try {
			dg.saveClassesToFiles(outputPath);
		}
		catch (java.io.IOException e) {
			System.err.println("Files could not be saved:");
			e.printStackTrace();
		}

		System.out.println("Done.");

		return 0;

	} // realMain

	//--------------------------------------------------------

	/**
	 * Auxiliary method to get a text template by its name.
	 * If it is not found, a message is sent to System.err
	 * and null is returned.
	 *
	 * @param name Template name. ".tmplt" extension will be
	 * added.
	 */
	protected static TextTemplate getTemplate(String name) {

		TextTemplate result;
		result = new TextTemplate();
		try {
			result.initFromFile(name + ".tmplt");
		}
		catch (Exception e) {
			System.err.println(name + ".tmplt template file cannot be found.");
			return null;
		}
		return result;

	} // getTemplate

	//--------------------------------------------------------
	//                   Protected fields
	//--------------------------------------------------------

	/**
	 * List with the names of each generated class. The names
	 * contain the complete package (for example
	 * <tt>towers.mmpm.entities.Wall</tt> instead of just
	 * <tt>Wall</tt>).
	 *
	 * The code for this class will be in the same position
	 * of the _generatedCode list.
	 */
	protected List<String> _generatedClassesNames;

	/**
	 * List with the java code of the generated class. The
	 * name of each class will be in the same position of
	 * the _generatedClassesNames list.
	 */
	protected List<String> _generatedCode;

} // class DomainGenerator


text:
CREATE TYPE cdb_dataservices_server.isoline AS (center geometry(Geometry,4326), data_range integer, the_geom geometry(Multipolygon,4326));

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_here_routing_isolines(username TEXT, orgname TEXT, type TEXT, source geometry(Geometry, 4326), mode TEXT, data_range integer[], options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  import json
  from cartodb_services.here import get_routing_isoline
  from cartodb_services.metrics import QuotaService
  from cartodb_services.here.types import geo_polyline_to_multipolygon
  from cartodb_services.tools import Logger,LoggerConfig

  redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
  user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]

  plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
  logger_config = GD["logger_config"]
  logger = Logger(logger_config)
  # -- Check the quota
  quota_service = QuotaService(user_isolines_routing_config, redis_conn)
  if not quota_service.check_user_quota():
    raise Exception('You have reached the limit of your quota')

  try:
    client = get_routing_isoline(app_id=user_isolines_routing_config.heremaps_app_id or None,
      app_code=user_isolines_routing_config.heremaps_app_code or None, logger=logger,
      apikey=user_isolines_routing_config.heremaps_apikey or None,
      use_apikey=user_isolines_routing_config.heremaps_use_apikey or False)
    client_api_version = client.get_api_version()
    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      if client_api_version == 7:
        source_str = 'geo!%f,%f' % (lat, lon)
      else:
        source_str = '%f,%f' % (lat, lon)
    else:
      source_str = None

    if type == 'isodistance':
      resp = client.calculate_isodistance(source_str, mode, data_range, options)
    elif type == 'isochrone':
      resp = client.calculate_isochrone(source_str, mode, data_range, options)

    if resp:
      result = []
      for isoline in resp:
        data_range_n = isoline['range']
        polyline = isoline['geom']
        multipolygon = geo_polyline_to_multipolygon(polyline)
        result.append([source, data_range_n, multipolygon])
      quota_service.increment_success_service_use()
      quota_service.increment_isolines_service_use(len(resp))
      return result
    else:
      quota_service.increment_empty_service_use()
      return []
  except BaseException as e:
    import sys
    quota_service.increment_failed_service_use()
    logger.error('Error trying to get mapzen isolines', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get mapzen isolines')
  finally:
    quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isodistance(
   username TEXT,
   orgname TEXT,
   source geometry(Geometry, 4326),
   mode TEXT,
   data_range integer[],
   options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  import json
  from cartodb_services.mapzen import MatrixClient, MapzenIsolines
  from cartodb_services.metrics import QuotaService
  from cartodb_services.tools import Logger,LoggerConfig

  redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
  user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]

  plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
  logger_config = GD["logger_config"]
  logger = Logger(logger_config)
  quota_service = QuotaService(user_isolines_routing_config, redis_conn)
  if not quota_service.check_user_quota():
    raise Exception('You have reached the limit of your quota')

  try:
    client = MatrixClient(user_isolines_routing_config.mapzen_matrix_api_key, logger, user_isolines_routing_config.mapzen_matrix_service_params)
    mapzen_isolines = MapzenIsolines(client, logger)

    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      origin = {'lat': lat, 'lon': lon}
    else:
      raise Exception('source is NULL')

    # -- TODO Support options properly
    isolines = {}
    for r in data_range:
        isoline = mapzen_isolines.calculate_isodistance(origin, mode, r)
        isolines[r] = isoline

    result = []
    for r in data_range:

      if len(isolines[r]) >= 3:
        # -- TODO encapsulate this block into a func/method
        locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point
        wkt_coordinates = ','.join(["%f %f" % (l['lon'], l['lat']) for l in locations])
        sql = "SELECT ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326) as geom".format(wkt_coordinates)
        multipolygon = plpy.execute(sql, 1)[0]['geom']
      else:
        multipolygon = None

      result.append([source, r, multipolygon])

    quota_service.increment_success_service_use()
    quota_service.increment_isolines_service_use(len(isolines))
    return result
  except BaseException as e:
    import sys
    quota_service.increment_failed_service_use()
    logger.error('Error trying to get mapzen isolines', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get mapzen isolines')
  finally:
    quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapbox_isodistance(
   username TEXT,
   orgname TEXT,
   source geometry(Geometry, 4326),
   mode TEXT,
   data_range integer[],
   options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  from cartodb_services.tools import ServiceManager
  from cartodb_services.mapbox import MapboxIsolines
  from cartodb_services.mapbox.types import TRANSPORT_MODE_TO_MAPBOX
  from cartodb_services.tools import Coordinate
  from cartodb_services.refactor.service.mapbox_isolines_config import MapboxIsolinesConfigBuilder

  import cartodb_services
  cartodb_services.init(plpy, GD)

  service_manager = ServiceManager('isolines', MapboxIsolinesConfigBuilder, username, orgname, GD)
  service_manager.assert_within_limits()

  try:
    mapbox_isolines = MapboxIsolines(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params)

    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      origin = Coordinate(lon,lat)
    else:
      raise Exception('source is NULL')

    profile = TRANSPORT_MODE_TO_MAPBOX.get(mode)

    # -- TODO Support options properly
    isolines = {}
    for r in data_range:
        isoline = mapbox_isolines.calculate_isodistance(origin, r, profile)
        isolines[r] = isoline

    result = []
    for r in data_range:

      if len(isolines[r]) >= 3:
        # -- TODO encapsulate this block into a func/method
        locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point
        wkt_coordinates = ','.join(["%f %f" % (l.longitude, l.latitude) for l in locations])
        sql = "SELECT ST_CollectionExtract(ST_MakeValid(ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326)),3) as geom".format(wkt_coordinates)
        multipolygon = plpy.execute(sql, 1)[0]['geom']
      else:
        multipolygon = None

      result.append([source, r, multipolygon])

    service_manager.quota_service.increment_success_service_use()
    service_manager.quota_service.increment_isolines_service_use(len(isolines))
    return result
  except BaseException as e:
    import sys
    service_manager.quota_service.increment_failed_service_use()
    service_manager.logger.error('Error trying to get Mapbox isolines', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get Mapbox isolines')
  finally:
    service_manager.quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_tomtom_isodistance(
   username TEXT,
   orgname TEXT,
   source geometry(Geometry, 4326),
   mode TEXT,
   data_range integer[],
   options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  from cartodb_services.tools import ServiceManager
  from cartodb_services.tomtom import TomTomIsolines
  from cartodb_services.tomtom.types import TRANSPORT_MODE_TO_TOMTOM
  from cartodb_services.tools import Coordinate
  from cartodb_services.refactor.service.tomtom_isolines_config import TomTomIsolinesConfigBuilder

  import cartodb_services
  cartodb_services.init(plpy, GD)

  service_manager = ServiceManager('isolines', TomTomIsolinesConfigBuilder, username, orgname, GD)
  service_manager.assert_within_limits()

  try:
    tomtom_isolines = TomTomIsolines(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params)

    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      origin = Coordinate(lon,lat)
    else:
      raise Exception('source is NULL')

    profile = TRANSPORT_MODE_TO_TOMTOM.get(mode)

    # -- TODO Support options properly
    isolines = {}
    for r in data_range:
        isoline = tomtom_isolines.calculate_isodistance(origin, r, profile)
        isolines[r] = isoline

    result = []
    for r in data_range:

      if len(isolines[r]) >= 3:
        # -- TODO encapsulate this block into a func/method
        locations = isolines[r] + [ isolines[r][0] ] # close the polygon repeating the first point
        wkt_coordinates = ','.join(["%f %f" % (l.longitude, l.latitude) for l in locations])
        sql = "SELECT ST_CollectionExtract(ST_MakeValid(ST_MPolyFromText('MULTIPOLYGON((({0})))', 4326)),3) as geom".format(wkt_coordinates)
        multipolygon = plpy.execute(sql, 1)[0]['geom']
      else:
        multipolygon = None

      result.append([source, r, multipolygon])

    service_manager.quota_service.increment_success_service_use()
    service_manager.quota_service.increment_isolines_service_use(len(isolines))
    return result
  except BaseException as e:
    import sys
    service_manager.quota_service.increment_failed_service_use()
    service_manager.logger.error('Error trying to get TomTom isolines', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get TomTom isolines')
  finally:
    service_manager.quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_isochrones(
   username TEXT,
   orgname TEXT,
   source geometry(Geometry, 4326),
   mode TEXT,
   data_range integer[],
   options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  import json
  from cartodb_services.mapzen import MatrixClient, MapzenIsochrones
  from cartodb_services.metrics import QuotaService
  from cartodb_services.tools import Logger,LoggerConfig
  from cartodb_services.mapzen.types import coordinates_to_polygon

  redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
  user_isolines_routing_config = GD["user_isolines_routing_config_{0}".format(username)]

  plpy.execute("SELECT cdb_dataservices_server._get_logger_config()")
  logger_config = GD["logger_config"]
  logger = Logger(logger_config)
  # -- Check the quota
  quota_service = QuotaService(user_isolines_routing_config, redis_conn)
  if not quota_service.check_user_quota():
    raise Exception('You have reached the limit of your quota')

  try:
    mapzen_isochrones = MapzenIsochrones(user_isolines_routing_config.mapzen_matrix_api_key,
                                         logger, user_isolines_routing_config.mapzen_isochrones_service_params)

    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      origin = {'lat': lat, 'lon': lon}
    else:
      raise Exception('source is NULL')

    resp = mapzen_isochrones.isochrone(origin, mode, data_range)

    if resp:
      result = []
      for isochrone in resp:
        result_polygon = coordinates_to_polygon(isochrone.coordinates)
        if result_polygon:
          result.append([source, isochrone.duration, result_polygon])
        else:
          result.append([source, isochrone.duration, None])
      quota_service.increment_success_service_use()
      quota_service.increment_isolines_service_use(len(result))
      return result
    else:
      quota_service.increment_empty_service_use()
      return []
  except BaseException as e:
    import sys
    quota_service.increment_failed_service_use()
    logger.error('Error trying to get mapzen isochrones', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get mapzen isochrones')
  finally:
    quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapbox_isochrones(
   username TEXT,
   orgname TEXT,
   source geometry(Geometry, 4326),
   mode TEXT,
   data_range integer[],
   options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  from cartodb_services.tools import ServiceManager
  from cartodb_services.mapbox import MapboxIsolines
  from cartodb_services.mapbox.types import TRANSPORT_MODE_TO_MAPBOX
  from cartodb_services.tools import Coordinate
  from cartodb_services.tools.coordinates import coordinates_to_polygon
  from cartodb_services.refactor.service.mapbox_isolines_config import MapboxIsolinesConfigBuilder

  import cartodb_services
  cartodb_services.init(plpy, GD)

  service_manager = ServiceManager('isolines', MapboxIsolinesConfigBuilder, username, orgname, GD)
  service_manager.assert_within_limits()

  try:
    mapbox_isolines = MapboxIsolines(service_manager.config.mapbox_api_key, service_manager.logger, service_manager.config.service_params)

    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      origin = Coordinate(lon,lat)
    else:
      raise Exception('source is NULL')

    profile = TRANSPORT_MODE_TO_MAPBOX.get(mode)

    resp = mapbox_isolines.calculate_isochrone(origin, data_range, profile)

    if resp:
      result = []
      for isochrone in resp:
        result_polygon = coordinates_to_polygon(isochrone.coordinates)
        if result_polygon:
          result.append([source, isochrone.duration, result_polygon])
        else:
          result.append([source, isochrone.duration, None])
      service_manager.quota_service.increment_success_service_use()
      service_manager.quota_service.increment_isolines_service_use(len(result))
      return result
    else:
      service_manager.quota_service.increment_empty_service_use()
      return []
  except BaseException as e:
    import sys
    service_manager.quota_service.increment_failed_service_use()
    service_manager.logger.error('Error trying to get Mapbox isochrones', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get Mapbox isochrones')
  finally:
    service_manager.quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;

CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_tomtom_isochrones(
   username TEXT,
   orgname TEXT,
   source geometry(Geometry, 4326),
   mode TEXT,
   data_range integer[],
   options text[])
RETURNS SETOF cdb_dataservices_server.isoline AS $$
  from cartodb_services.tools import ServiceManager
  from cartodb_services.tomtom import TomTomIsolines
  from cartodb_services.tomtom.types import TRANSPORT_MODE_TO_TOMTOM
  from cartodb_services.tools import Coordinate
  from cartodb_services.tools.coordinates import coordinates_to_polygon
  from cartodb_services.refactor.service.tomtom_isolines_config import TomTomIsolinesConfigBuilder

  import cartodb_services
  cartodb_services.init(plpy, GD)

  service_manager = ServiceManager('isolines', TomTomIsolinesConfigBuilder, username, orgname, GD)
  service_manager.assert_within_limits()

  try:
    tomtom_isolines = TomTomIsolines(service_manager.config.tomtom_api_key, service_manager.logger, service_manager.config.service_params)

    if source:
      lat = plpy.execute("SELECT ST_Y('%s') AS lat" % source)[0]['lat']
      lon = plpy.execute("SELECT ST_X('%s') AS lon" % source)[0]['lon']
      origin = Coordinate(lon,lat)
    else:
      raise Exception('source is NULL')

    profile = TRANSPORT_MODE_TO_TOMTOM.get(mode)

    resp = tomtom_isolines.calculate_isochrone(origin, data_range, profile)

    if resp:
      result = []
      for isochrone in resp:
        result_polygon = coordinates_to_polygon(isochrone.coordinates)
        if result_polygon:
          result.append([source, isochrone.duration, result_polygon])
        else:
          result.append([source, isochrone.duration, None])
      service_manager.quota_service.increment_success_service_use()
      service_manager.quota_service.increment_isolines_service_use(len(result))
      return result
    else:
      service_manager.quota_service.increment_empty_service_use()
      return []
  except BaseException as e:
    import sys
    service_manager.quota_service.increment_failed_service_use()
    service_manager.logger.error('Error trying to get TomTom isochrones', sys.exc_info(), data={"username": username, "orgname": orgname})
    raise Exception('Error trying to get TomTom isochrones')
  finally:
    service_manager.quota_service.increment_total_service_use()
$$ LANGUAGE @@plpythonu@@ SECURITY DEFINER STABLE PARALLEL RESTRICTED;


text:
import React from 'react';
import {
  AdminContext,
  ResourceContextProvider,
  Tab,
  TextField,
} from 'react-admin';
import { Resource } from '@api-platform/api-doc-parser';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import ShowGuesser from './ShowGuesser.js';
import SchemaAnalyzerContext from './SchemaAnalyzerContext.js';
import schemaAnalyzer from './hydra/schemaAnalyzer.js';
import type {
  ApiPlatformAdminDataProvider,
  ApiPlatformAdminRecord,
} from './types.js';

import { API_FIELDS_DATA } from './__fixtures__/parsedData.js';

const hydraSchemaAnalyzer = schemaAnalyzer();
const dataProvider: ApiPlatformAdminDataProvider = {
  getList: () => Promise.resolve({ data: [], total: 0 }),
  getMany: () => Promise.resolve({ data: [] }),
  getManyReference: () => Promise.resolve({ data: [], total: 0 }),
  update: <RecordType extends ApiPlatformAdminRecord>() =>
    Promise.resolve({ data: { id: 'id' } } as { data: RecordType }),
  updateMany: () => Promise.resolve({ data: [] }),
  create: <RecordType extends ApiPlatformAdminRecord>() =>
    Promise.resolve({ data: { id: 'id' } } as { data: RecordType }),
  delete: <RecordType extends ApiPlatformAdminRecord>() =>
    Promise.resolve({ data: { id: 'id' } } as { data: RecordType }),
  deleteMany: () => Promise.resolve({ data: [] }),
  getOne: () =>
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    Promise.resolve({
      data: {
        id: '/users/123',
        fieldA: 'fieldA value',
        fieldB: 'fieldB value',
        deprecatedField: 'deprecatedField value',
        title: 'Title',
        body: 'Body',
      },
    }),
  introspect: () =>
    Promise.resolve({
      data: {
        entrypoint: 'entrypoint',
        resources: [
          new Resource('users', '/users', {
            fields: API_FIELDS_DATA,
            readableFields: API_FIELDS_DATA,
            writableFields: API_FIELDS_DATA,
            parameters: [],
          }),
        ],
      },
    }),
  subscribe: () => Promise.resolve({ data: null }),
  unsubscribe: () => Promise.resolve({ data: null }),
};

describe('<ShowGuesser />', () => {
  test('renders with no children', async () => {
    render(
      <AdminContext dataProvider={dataProvider}>
        <SchemaAnalyzerContext.Provider value={hydraSchemaAnalyzer}>
          <ResourceContextProvider value="users">
            <ShowGuesser id="/users/123" />
          </ResourceContextProvider>
        </SchemaAnalyzerContext.Provider>
      </AdminContext>,
    );

    await waitFor(() => {
      expect(
        screen.queryAllByText('resources.users.fields.fieldA'),
      ).toHaveLength(1);
      expect(screen.queryAllByText('fieldA value')).toHaveLength(1);
      expect(
        screen.queryAllByText('resources.users.fields.fieldB'),
      ).toHaveLength(1);
      expect(screen.queryAllByText('fieldB value')).toHaveLength(1);
      expect(
        screen.queryAllByText('resources.users.fields.deprecatedField'),
      ).toHaveLength(0);
      expect(screen.queryAllByText('deprecatedField value')).toHaveLength(0);
    });
  });

  test('renders with custom fields', async () => {
    render(
      <AdminContext dataProvider={dataProvider}>
        <SchemaAnalyzerContext.Provider value={hydraSchemaAnalyzer}>
          <ShowGuesser resource="users" id="/users/123">
            <TextField source="id" label="label of id" />
            <TextField source="title" label="label of title" />
            <TextField source="body" label="label of body" />
          </ShowGuesser>
        </SchemaAnalyzerContext.Provider>
      </AdminContext>,
    );

    await waitFor(() => {
      expect(screen.queryAllByText('label of id')).toHaveLength(1);
      expect(screen.queryAllByText('/users/123')).toHaveLength(1);
      expect(screen.queryAllByText('label of title')).toHaveLength(1);
      expect(screen.queryAllByText('Title')).toHaveLength(1);
      expect(screen.queryAllByText('label of body')).toHaveLength(1);
      expect(screen.queryAllByText('Body')).toHaveLength(1);
    });
  });

  test.each([0, 1])('renders with tabs', async (tabId) => {
    const user = userEvent.setup();

    render(
      <AdminContext dataProvider={dataProvider}>
        <SchemaAnalyzerContext.Provider value={hydraSchemaAnalyzer}>
          <ShowGuesser resource="users" id="/users/123">
            <Tab label="Tab 1">
              <TextField source="id" label="label of id" />
              <TextField source="title" label="label of title" />
            </Tab>
            <Tab label="Tab 2">
              <TextField source="body" label="label of body" />
            </Tab>
          </ShowGuesser>
        </SchemaAnalyzerContext.Provider>
      </AdminContext>,
    );

    await waitFor(async () => {
      expect(screen.queryAllByRole('tab')).toHaveLength(2);
      const tab = screen.getAllByRole('tab')[tabId];
      if (tab) {
        await user.click(tab);
      }

      // First tab, available for tabId == 0.
      expect(screen.queryAllByText('label of id')).toHaveLength(tabId ? 0 : 1);
      expect(screen.queryAllByText('/users/123')).toHaveLength(tabId ? 0 : 1);
      expect(screen.queryAllByText('label of title')).toHaveLength(
        tabId ? 0 : 1,
      );
      expect(screen.queryAllByText('Title')).toHaveLength(tabId ? 0 : 1);
      // Second tab, available for tabId == 1.
      expect(screen.queryAllByText('label of body')).toHaveLength(
        tabId ? 1 : 0,
      );
      expect(screen.queryAllByText('Body')).toHaveLength(tabId ? 1 : 0);
    });
  });
});