text:
/**
 * @test
 * @bug 6220064
 * @summary make sure everything works ok in the Turkish local (dotted/dotless i problem)
 * @run main/othervm Turkish
 * @author Andreas Sterbenz
 */

import java.util.*;

import java.security.*;
import java.security.Provider.Service;
import javax.crypto.*;

public class Turkish {

    public static void main(String[] args) throws Exception {
        Provider p1 = new TProvider("T1");
        System.out.println(p1.getServices()); // trigger service parsing

        Locale.setDefault(new Locale("tr", "TR"));

        Provider p2 = new TProvider("T2");
        System.out.println(p2.getServices()); // trigger service parsing

        System.out.println(Signature.getInstance("MD5withRSA"));
        System.out.println(Signature.getInstance("md5withrsa"));
        System.out.println(Signature.getInstance("MD5WITHRSA"));
        Service s1, s2;
        s1 = p1.getService("Signature", "MD5withRSA");
        check(s1, null);
        check(s1, p1.getService("Signature", "md5withrsa"));
        check(s1, p1.getService("Signature", "MD5WITHRSA"));
        check(s1, p1.getService("Signature", "MD5RSA"));
        check(s1, p1.getService("Signature", "md5rsa"));
        check(s1, p1.getService("Signature", "MD5rsa"));

        s1 = p1.getService("Signature", "SHAwithRSA");
        check(s1, null);
        check(s1, p1.getService("Signature", "shawithrsa"));
        check(s1, p1.getService("Signature", "SHAWITHRSA"));
        check(s1, p1.getService("Signature", "SHARSA"));
        check(s1, p1.getService("Signature", "sharsa"));
        check(s1, p1.getService("Signature", "SHArsa"));
        check(s1, p1.getService("Signature", "SHA1RSA"));
        check(s1, p1.getService("Signature", "sha1rsa"));
        check(s1, p1.getService("Signature", "SHA1rsa"));

        s1 = p2.getService("Signature", "MD5withRSA");
        check(s1, null);
        check(s1, p2.getService("Signature", "md5withrsa"));
        check(s1, p2.getService("Signature", "MD5WITHRSA"));
        check(s1, p2.getService("Signature", "MD5RSA"));
        check(s1, p2.getService("Signature", "md5rsa"));
        check(s1, p2.getService("Signature", "MD5rsa"));

        s1 = p2.getService("Signature", "SHAwithRSA");
        check(s1, null);
        check(s1, p2.getService("Signature", "shawithrsa"));
        check(s1, p2.getService("Signature", "SHAWITHRSA"));
        check(s1, p2.getService("Signature", "SHARSA"));
        check(s1, p2.getService("Signature", "sharsa"));
        check(s1, p2.getService("Signature", "SHArsa"));
        check(s1, p2.getService("Signature", "SHA1RSA"));
        check(s1, p2.getService("Signature", "sha1rsa"));
        check(s1, p2.getService("Signature", "SHA1rsa"));

        System.out.println("OK");
    }

    private static void check(Service s1, Service s2) throws Exception {
        System.out.println(s1);
        if (s1 == null) {
            throw new Exception("service is null");
        }
        if ((s2 != null) && (s1 != s2)) {
            throw new Exception("service does not match");
        }
    }

    private static class TProvider extends Provider {
        TProvider(String name) {
            super(name, 1.0d, null);
            put("Signature.MD5withRSA", "com.foo.Sig");
            put("Alg.Alias.Signature.MD5RSA", "MD5withRSA");
            put("sIGNATURE.shaWITHrsa", "com.foo.Sig");
            put("aLG.aLIAS.sIGNATURE.sharsa", "shaWITHrsa");
            put("aLG.aLIAS.sIGNATURE.sha1rsa", "shawithrsa");
        }
    }

}


text:
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');

//call express as app
const app = express();

//Setting up paths for frontend
module.exports = (app, express) => {
  app.use(express.static(path.join(__dirname, '/../node_modules')));
  app.use(express.static(path.join(__dirname, '/../client')));
};

//connect to mongo database named 'AppTrack'
//heroku, make project, mlab is available as heroku add-on

//const url = 'mongodb://localhost/AppTrack';
//mongoose.connect(url);

//Display the index as homepage
app.get('/',(request, response) => {
  response.sendfile('client/index.html');
});

app.post('/',(request, response) => {
	console.log(request.body);
})

//set up the server on env.PORT or 8080
const port = process.env.PORT || 8080;
app.listen(port, (err) => {
  if(err) {
    return console.log('Error occurred: ', err);
  }
  console.log('Server is listening on port: ', port);
})

redpajama_set_name: RedPajamaGithub


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Grevillea 1(no. 11): 175 (1873)

#### Original name
Bolacotricha grisea Berk. & Broome, 1851

### Remarks
null


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="shortcut icon" href="favicon.ico">

    <title>Justin Alvey</title>

    <link href="assets/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

    <link href="assets/css/style.css" rel="stylesheet">
    <link href="assets/css/font-awesome.min.css" rel="stylesheet">

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            Toggle navigation

          </button>
          JAlvey

Home

Resume/CV

Projects

SOFTWARE PROJECTS

Data Analysis

					>

Object-Oriented Programming

Software Development

Michigan Native

Software Engineer

Boulder, CO

justin.alvey@colorado.edu


text:
import React from 'react';
import TestRenderer from 'react-test-renderer';

function createComponent(jsx) {
  return TestRenderer.create(jsx);
}

export default createComponent;


text:
package git

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
)

var (
	ErrRepositoryNotFound = errors.New("Repository not found.")
)

// DiscoverRepositoryPath finds the path of the repository from a given
// directory. It returns the path to the repository, or an an empty string and
// a non-nil error if it can't find the repository.
func DiscoverRepositoryPath(dir string) (string, error) {
	_, err := os.Stat(dir)
	if os.IsNotExist(err) {
		return "", ErrRepositoryNotFound
	}
	dir = filepath.Join(dir, ".git")
	for dir != "/.git" {
		fi, err := os.Stat(dir)
		if err == nil && fi.IsDir() {
			return dir, nil
		}
		dir = filepath.Join(dir, "..", "..", ".git")
	}
	return "", ErrRepositoryNotFound
}

// Repository represents a git repository.
type Repository struct {
	path string
}

// OpenRepository opens a repository by its filepath. You can use
// DiscoverRepositoryPath to discover the repository from any directory, and
// use the result of this call as parameter for OpenRepository.
//
// OpenRepository will return an error if the given path does not appear to be
// a git repository.
func OpenRepository(p string) (*Repository, error) {
	if !strings.HasSuffix(p, ".git") && !strings.HasSuffix(p, ".git/") {
		p = filepath.Join(p, ".git")
	}
	p = strings.TrimRight(p, "/")
	fi, err := os.Stat(filepath.Join(p, "config"))
	if err == nil && !fi.IsDir() {
		return &Repository{path: p}, nil
	}
	return nil, ErrRepositoryNotFound
}

// RemoteURL returns the URL of a remote by its name. Or an error, if the
// remote is not declared.
func (r *Repository) RemoteURL(name string) (string, error) {
	config, err := os.Open(filepath.Join(r.path, "config"))
	if err != nil {
		return "", err
	}
	defer config.Close()
	line := fmt.Sprintf("[remote %q]", name)
	scanner := bufio.NewScanner(config)
	scanner.Split(bufio.ScanLines)
	for scanner.Scan() {
		if scanner.Text() == line {
			scanner.Scan()
			return strings.Split(scanner.Text(), " = ")[1], nil
		}
	}
	return "", errRemoteNotFound{name}
}

type errRemoteNotFound struct {
	name string
}

func (e errRemoteNotFound) Error() string {
	return fmt.Sprintf("Remote %q not found.", e.name)
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Ceská Mykol. 41(1): 17 (1987)

#### Original name
Albotricha lupini Svrcek

### Remarks
null


text:
<?php
namespace Chamilo\Core\Repository\Implementation\Office365Video\Component;

use Chamilo\Core\Repository\Implementation\Office365Video\Manager;
use Chamilo\Core\Repository\Instance\Storage\DataClass\Setting;
use Chamilo\Libraries\Platform\Translation;
use Chamilo\Libraries\Utilities\Utilities;

class LoginComponent extends Manager
{

    public function run()
    {
        $setting = \Chamilo\Core\Repository\Instance\Storage\DataManager::retrieveUserSetting(
            $this->get_external_repository()->getId(),
            $this->getUser()->getId(),
            'session_token');

        if (! $setting instanceof Setting)
        {
            if ($this->get_external_repository_manager_connector()->login())
            {
                $parameters = $this->get_parameters();
                $parameters[Manager::PARAM_ACTION] = Manager::ACTION_BROWSE_EXTERNAL_REPOSITORY;
                $this->redirect(
                    Translation::get('LoginSuccessful', null, Utilities::COMMON_LIBRARIES),
                    false,
                    $parameters);
            }
            else
            {

                $parameters = $this->get_parameters();
                $parameters[Manager::PARAM_ACTION] = Manager::ACTION_BROWSE_EXTERNAL_REPOSITORY;
                $this->redirect(Translation::get('LoginFailed', null, Utilities::COMMON_LIBRARIES), true, $parameters);
            }
        }
        else
        {
            $parameters = $this->get_parameters();
            $parameters[Manager::PARAM_ACTION] = Manager::ACTION_BROWSE_EXTERNAL_REPOSITORY;
            $this->redirect('', false, $parameters);
        }
    }
}


text:
package org.jboss.weld.tests.serialization.annotated;

import static org.junit.Assert.assertEquals;

import java.lang.reflect.Modifier;

import jakarta.enterprise.inject.spi.AnnotatedConstructor;
import jakarta.enterprise.inject.spi.AnnotatedField;
import jakarta.enterprise.inject.spi.AnnotatedMethod;
import jakarta.enterprise.inject.spi.AnnotatedParameter;
import jakarta.enterprise.inject.spi.AnnotatedType;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.BeanArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.weld.test.util.Utils;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class BackedAnnotatedTypeSerializationTest {

    @Inject
    protected FooExtension extension;

    @Deployment
    public static Archive<?> getDeployment() {
        return ShrinkWrap.create(BeanArchive.class, Utils.getDeploymentNameAsHash(BackedAnnotatedTypeSerializationTest.class)).addPackage(BackedAnnotatedTypeSerializationTest.class.getPackage())
                .addClass(Utils.class).addAsServiceProvider(Extension.class, FooExtension.class);
    }

    public AnnotatedType<Foo> getAnnotatedType() {
        return extension.getBackedAnnotatedType();
    }

    @Test
    public void testType() throws Exception {
        AnnotatedType<?> type = Utils.deserialize(Utils.serialize(getAnnotatedType()));
        assertEquals(2, type.getAnnotations().size());
    }

    @Test
    public void testFields() throws Exception {
        for (AnnotatedField<?> field : getAnnotatedType().getFields()) {
            AnnotatedField<?> deserialized = Utils.deserialize(Utils.serialize(field));
            assertEquals(1, deserialized.getAnnotations().size());
        }
    }

    @Test
    public void testMethods() throws Exception {
        for (AnnotatedMethod<?> method : getAnnotatedType().getMethods()) {
            AnnotatedMethod<?> deserialized = Utils.deserialize(Utils.serialize(method));
            assertEquals(1, deserialized.getAnnotations().size());
            assertEquals(3, deserialized.getParameters().size());
        }
    }

    @Test
    public void testConstructors() throws Exception {
        for (AnnotatedConstructor<?> constructor : getAnnotatedType().getConstructors()) {
            if (!Modifier.isPublic(constructor.getJavaMember().getModifiers())) {
                continue;
            }
            AnnotatedConstructor<?> deserialized = Utils.deserialize(Utils.serialize(constructor));
            assertEquals(2, deserialized.getParameters().size());
        }
    }

    @Test
    public void testParameters() throws Exception {
        for (AnnotatedConstructor<?> constructor : getAnnotatedType().getConstructors()) {
            for (AnnotatedParameter<?> parameter : constructor.getParameters()) {
                testParameter(parameter);
            }
        }
        for (AnnotatedMethod<?> method : getAnnotatedType().getMethods()) {
            for (AnnotatedParameter<?> parameter : method.getParameters()) {
                testParameter(parameter);
            }
        }
    }

    private void testParameter(AnnotatedParameter<?> parameter) throws Exception {
        Utils.deserialize(Utils.serialize(parameter));
    }
}


text:
#include "cubeproxygeometry.h"
#include <inviwo/core/datastructures/geometry/simplemeshcreator.h>
#include <inviwo/core/network/networklock.h>

namespace inviwo {

const ProcessorInfo CubeProxyGeometry::processorInfo_{
    "org.inviwo.CubeProxyGeometry",  // Class identifier
    "Cube Proxy Geometry",           // Display name
    "Geometry Creation",             // Category
    CodeState::Stable,               // Code state
    Tags::CPU,                       // Tags
};
const ProcessorInfo CubeProxyGeometry::getProcessorInfo() const {
    return processorInfo_;
}

CubeProxyGeometry::CubeProxyGeometry()
    : Processor()
    , inport_("volume")
    , outport_("proxyGeometry")
    , clippingEnabled_("clippingEnabled", "Enable Clipping", true)
    , clipX_("clipX", "Clip X Slices", 0, 256, 0, 256, 1, 1)
    , clipY_("clipY", "Clip Y Slices", 0, 256, 0, 256, 1, 1)
    , clipZ_("clipZ", "Clip Z Slices", 0, 256, 0, 256, 1, 1) {

    addPort(inport_);
    addPort(outport_);
    addProperty(clippingEnabled_);
    addProperty(clipX_);
    addProperty(clipY_);
    addProperty(clipZ_);

    // Since the clips depend on the input volume dimensions, we make sure to always
    // serialize them so we can do a proper renormalization when we load new data.
    clipX_.setSerializationMode(PropertySerializationMode::All);
    clipY_.setSerializationMode(PropertySerializationMode::All);
    clipZ_.setSerializationMode(PropertySerializationMode::All);

    inport_.onChange(this, &CubeProxyGeometry::onVolumeChange);
}

CubeProxyGeometry::~CubeProxyGeometry() {}

void CubeProxyGeometry::process() {
    vec3 startDataTexCoord = vec3(0.0f);
    vec3 extent = vec3(1.0f); //!< will be added to the origin in the parallelepiped() yielding the end position

    if (inport_.getData()->getMetaData<BoolMetaData>("marginsEnabled", false)) {
        // volume has margins enabled
        // adjust start and end texture coordinate accordingly
        auto marginsBottomLeft = inport_.getData()->getMetaData<FloatVec3MetaData>("marginsBottomLeft", vec3(0.0f));
        auto marginsTopRight = inport_.getData()->getMetaData<FloatVec3MetaData>("marginsTopRight", vec3(0.0f));

        startDataTexCoord += marginsBottomLeft;
        // extent needs to be adjusted for both margins
        extent -= marginsBottomLeft + marginsTopRight;
    }

    glm::vec3 pos(0.0f);
    glm::vec3 p1(1.0f, 0.0f, 0.0f);
    glm::vec3 p2(0.0f, 1.0f, 0.0f);
    glm::vec3 p3(0.0f, 0.0f, 1.0f);
    glm::vec3 tex(startDataTexCoord);
    glm::vec3 t1(extent.x, 0.0f, 0.0f);
    glm::vec3 t2(0.0f, extent.y, 0.0f);
    glm::vec3 t3(0.0f, 0.0f, extent.z);
    glm::vec4 col(startDataTexCoord, 1.0f);
    glm::vec4 c1(t1, 0.0f);
    glm::vec4 c2(t2, 0.0f);
    glm::vec4 c3(t3, 0.0f);
    auto dims = inport_.getData()->getDimensions();

    if (clippingEnabled_.get()) {
        pos = pos + p1*static_cast<float>(clipX_.get().x)/static_cast<float>(dims.x)
                  + p2*static_cast<float>(clipY_.get().x)/static_cast<float>(dims.y)
                  + p3*static_cast<float>(clipZ_.get().x)/static_cast<float>(dims.z);
        p1 = p1*(static_cast<float>(clipX_.get().y)-static_cast<float>(clipX_.get().x))/static_cast<float>(dims.x);
        p2 = p2*(static_cast<float>(clipY_.get().y)-static_cast<float>(clipY_.get().x))/static_cast<float>(dims.y);
        p3 = p3*(static_cast<float>(clipZ_.get().y)-static_cast<float>(clipZ_.get().x))/static_cast<float>(dims.z);
        tex = tex + t1*static_cast<float>(clipX_.get().x)/static_cast<float>(dims.x)
                  + t2*static_cast<float>(clipY_.get().x)/static_cast<float>(dims.y)
                  + t3*static_cast<float>(clipZ_.get().x)/static_cast<float>(dims.z);
        t1 = t1*(static_cast<float>(clipX_.get().y)-static_cast<float>(clipX_.get().x))/static_cast<float>(dims.x);
        t2 = t2*(static_cast<float>(clipY_.get().y)-static_cast<float>(clipY_.get().x))/static_cast<float>(dims.y);
        t3 = t3*(static_cast<float>(clipZ_.get().y)-static_cast<float>(clipZ_.get().x))/static_cast<float>(dims.z);
        col = col + c1*static_cast<float>(clipX_.get().x)/static_cast<float>(dims.x)
                  + c2*static_cast<float>(clipY_.get().x)/static_cast<float>(dims.y)
                  + c3*static_cast<float>(clipZ_.get().x)/static_cast<float>(dims.z);
        c1 = c1*(static_cast<float>(clipX_.get().y)-static_cast<float>(clipX_.get().x))/static_cast<float>(dims.x);
        c2 = c2*(static_cast<float>(clipY_.get().y)-static_cast<float>(clipY_.get().x))/static_cast<float>(dims.y);
        c3 = c3*(static_cast<float>(clipZ_.get().y)-static_cast<float>(clipZ_.get().x))/static_cast<float>(dims.z);
    }

    // Create parallelepiped and set it to the outport. The outport will own the data.
    auto geom = SimpleMeshCreator::parallelepiped(pos, p1, p2, p3,
                                                  tex, t1, t2, t3,
                                                  col, c1, c2, c3);
    geom->setModelMatrix(inport_.getData()->getModelMatrix());
    geom->setWorldMatrix(inport_.getData()->getWorldMatrix());
    outport_.setData(geom);
}

void CubeProxyGeometry::onVolumeChange() {
    // Update to the new dimensions.
    auto dims = inport_.getData()->getDimensions();
    if (dims != size3_t(clipX_.getRangeMax(), clipY_.getRangeMax(), clipZ_.getRangeMax())) {
        NetworkLock lock(this);

        clipX_.setRangeNormalized(ivec2(0, dims.x));
        clipY_.setRangeNormalized(ivec2(0, dims.y));
        clipZ_.setRangeNormalized(ivec2(0, dims.z));

        // set the new dimensions to default if we were to press reset
        clipX_.setCurrentStateAsDefault();
        clipY_.setCurrentStateAsDefault();
        clipZ_.setCurrentStateAsDefault();
    }

}

} // namespace


text:
\documentclass[letter,11pt]{article}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{mathrsfs}
%\usepackage{lucidabr}
%\usepackage{yhmath}
%\usepackage{palatino}
\usepackage{amsmath,amssymb}
%\usepackage{graphics, psfig}
\usepackage[all]{xy}
\usepackage{alltt}

\input{macro}

\title{Internal Program Representation for \ThePivot}

\author{G.~Dos~Reis \and B.~Stroustrup}
\date{}

\begin{document}
\maketitle

\section{Introduction}
\label{sec:intro}

\ThePivot{} framework is a general infrastructure for transformation and
static analysis of programs written in C++ programming language. This document
serves as a refenrece manual for the internal program represenation use in the
\ThePivot{} framework.  A companion
document~\cite{dosreis04:ipr-user-guide} provides a user point of view.

%% \begin{alltt}\small
%%   \begin{note}
%%     Include examples on the max function.
%%   \end{note}
%% \end{alltt}

This document is structured as follows. The next subsections introduce general
notions of the language used to represent C++ entities.
%% The second part
%% \secref{sec:intro:organization} explains how the IPR library is organized.
 Then \secref{sec:interface-classes} go on describing the
interface of the various categories of nodes used in IPR. After that,
\secref{sec:impl} discusses the implementations of those interfaces.  Finally,
\secref{sec:xpr-grammar} gives a formal definition of XPR, the concrete syntax
for the external representation of programs in \ThePivot{}.

\subsection{The problem, solutions space and design choices}
\label{sec:design}

See \cite{stroustrup02:xti, gdr-bs05:cxx-rep}.

\subsection{General notions}
\label{sec:intro:general-notion}

A program is internally represented as a graph.  The nodes represents various
notions, such as types, expresssions, declarations, scopes, names...

A (well-formed) program written in C++ is composed of instantiation units.
Instantiation units are obtained from translation units after template
instantiation requests satisfaction.  Consequently, most IPR notions are
driven by declarations.

\subsubsection{Declaration}
\label{sec:intro:general-notion:declaration}
A \emph{declaration} is a specification of a \emph{type}, a set of
\emph{attributes}, and an optional initialier for a name.  The type dictates
the major mode of interpretation of the name.  The attributes or
\emph{declaration specifiers} supply additional interpretations or modifiers
the major mode.  The initializer is the expression the value of which the
name evaluates to, until eventual assignment to another value (if permitted by
the type).  This notion of declaration covers a wide range of situations.
Example:

\begin{minipage}[t]{12cm}
  \begin{minipage}[t]{5cm}
    \centering{\textit{C++}}
    \begin{Program}
  int counter = 0;

  struct point \{
    int x;
    int y;
  \};

  int next(int x) \{
    return x + 1;
  \}

  template<int N>
  struct buffer \{
     char data[N];
  \};

    \end{Program}
  \end{minipage}\hfil \vrule \hfil
  \begin{minipage}[t]{5cm}
    \centering{\textit{XPR}}
    \begin{Program}
  counter : int = 0;

  point : class = \{
    x : int;
    y : int;
  \};

  next : (x : int) int = \{
    return x + 1;
  \}

  buffer : <N : int> class = \{
    data : [N] char;
  \};
    \end{Program}
  \end{minipage}
\end{minipage}

In this example, the same program is expressed in both standard C++ and XPR
notations.  All the declarations follow the same pattern (which is probably
more stricking in the XPR notation): a name, a type, and an initializer.  In
particular, the class body and the function body are the initializers for the
class \texttt{point} and \texttt{next}, repsectively.  The name \texttt{point}
is declared to have type \texttt{class}.

In some regions, a declaration can be repeated many times. The first
 declaration for a name (with a given type) in a given region is
 called the \emph{master declaration} of that name in that region.

\subsubsection{Type}
\label{sec:intro:general-notion:type}

In IPR, a \emph{type} is conceived of as a collection of values or objects
with operations or functions.  This is not the most abstract definition of
type in circulation, but it is sufficiently general and close to the
general aims of the \ThePivot{} framework.  A type in IPR is a notion similar
to that of category~\cite{mac-lane01:categories}, it is a notion used to
describe a collection of objects with given properties.  In similar ways, the
notion of category can be used to talk about collection of categories, types
in IPR are expressions that have types.  For example, the class \texttt{ios}
of the previous section has type \texttt{class}, just like
the enumerator \texttt{ios::dec} has type \texttt{ios::flags} and the
enumeration \texttt{ios::flags} has type \texttt{enum}.

\subsubsection{Overloading}
\label{sec:intro:general-notion:overloading}
Most regions can contain different declarations with a given name.  Such
declarations are either redeclarations or declarations that use
different types.  A name is said to be  \emph{overloaded} in a given region if
that region contains at least two declarations specifying different types for
that name.  This concept of overloading is uniformly applied in IPR.  In
particular, any declaration can be overloaded, not just function declaration.
So the following fragment (in XPR notation) is valid.
\begin{Program}
  pi : double = 3.141592653589793;
  pi : float = 3.141592654f;
\end{Program}

That program frgament cannot be written directly in C++, as only functions
can be overloaded in Standard C++.  However it could be emulated, in
some specific cases, as a function object:
\begin{Program}
  struct pi \{
    operator double() const \{ return 3.141592653589793; \}
    operator float() const \{ return 3.141592654f; \}
  \};
\end{Program}

Given a name in some scope, the collection of all declarations for that name
is called its \emph{overload set}.

\subsubsection{Scope}
\label{sec:intro:general-notion:scope}
A \emph{scope} is a sequence of declarations. This notion is much more
general than that of Standard C++.  Obviously, the set of all declarations in
a given region is a scope.  So is the union of the results of looking a name
in a collection of regions.  That notion sets an elegant way to
account for the base classes in a class definition or the enumerators in
an enumeration definition.  Consider the following declarations:
\begin{center}
  \begin{minipage}[t]{6cm}
    \centering{C++}
    \begin{Program}
struct ios \{
  enum flags \{
    boolapha, dec, fixed,
    // ...
  \};
  // ...
\};

struct istream : virtual ios \{
  // ...
\};

struct ostream : virtual ios \{
  // ...
\};

struct stream : istream,
                ostream \{
  // ...
\};
    \end{Program}
  \end{minipage}\hfil \vrule \hfil
  \begin{minipage}[t]{6cm}
    \centering{XPR}
    \begin{Program}
ios :class \{
  flags :enum \{
    boolapha, dec, fixed,
    // ...
  \};
  // ...
\};

istream :class (ios public virtual) \{
  // ...
\};

ostream :class (ios public virtual) \{
  // ...
\};

stream :class (istream public,
               ostream public) \{
  // ...
\};
    \end{Program}
  \end{minipage}
\end{center}

The sequence of declarations for \texttt{ios}, \texttt{istream},
\texttt{ostream} and \texttt{stream}, appearing at toplevel, forms a scope.
So is the sequence of enumerators \texttt{ios::booalpha}, \texttt{ios::dec},
\texttt{ios::fixed}, ...  since they are for \emph{emplicitly declared}
named constants.  Similarly, the sequence of the base classes
\texttt{istream} and \texttt{ostream} of class \texttt{stream} is  a scope.
It is the sequence of \emph{implicitly declared} subjects with the
\texttt{public} declaration specifier.  Finally, the declaration for classes
\texttt{istream} and \texttt{ostream} says that their base scopes consist in
a single (implicit) declaration with specifiers \texttt{public} and
\texttt{virtual}.

%% A scope also supports the operation of lookup by name.  The result of that
%% operation usually is a set of declarations that can be partitionned into
%% subsets of declarations that specify the same type for the looked-up name.
%% Those subsets are called \emph{decl-sets}.  The collection of the decl-sets is
%% known as \emph{overload-set},  discussed in
%% \secref{sec:general-notion:overload-set}.

%% \subsubsection{Overload set}
%% \label{sec:general-notion:overload-set}
%% In general, the result of looking up a name in a given scope
%% (\secref{sec:intro:general-notion:scope}) is a set of
%% declarations, called the \emph{overload set} of that name in that scope.
%% %(Note: an overload set is something that grows up as the scope is being filled
%% %with declarations).
%% Members of an overload set are distinguished by their types
%% (\secref{sec:intro:general-notion:type}).  So, an overload set supports lookup
%% by types, in the same way a scope supports lookup by name.  The result
%% os subscripting an overload-set by a type is a declaration.
%% %is the master declaration.
%% \begin{note} Mention master declaration, secondary declaration and
%%   relationship between them. \end{note}

%% \subsubsection{Sequence}
%% \label{sec:intro:general-notion:sequence}
%% A \emph{sequence} is a map $I\longrightarrow T$ where the domain $I$ is a
%% subset of set of integers $\mathds{N}$.  Sequences considered in IPR have
%% bounded domains.  Therefore, when we speak of a sequence it is implicitly
%% understood to have a bounded domain. The cardinal of the domain of a sequence
%% is its \emph{size}.  A sequence $I\stackrel{\Sigma}{\longrightarrow} T$ of
%% size $n$ can be, canonically, decomposed into a chain of two maps
%% $I\stackrel{\nu}{\longrightarrow} [0,n)\longrightarrow T$ where the map $\nu$,
%% a numbering of the domain, is an increasing function.

%% \subsubsection{Iterator}
%% \label{sec:intro:general-notion:iterator}
%% An \emph{iterator} is a pair of a sequence and an integer called
%% \emph{position}.  An iterator $(s, i)$ is \emph{valid for indirection} if its
%% position $i$ is in the range of the numbering domain for $s$, \ie{} if $i$ is
%% nonnegative and less than the size of the sequence $s$.  The distinguished
%% iterators $(s, 0)$ and $(s, \mathit{size}(n))$ are called \emph{first} and
%% \emph{one-past-the-end} iterators, respectively.

%% \subsection{Unified type nodes}
%% \label{sec:into.type.unified}

%% IPR represents C++ programs as set of graphs and offers an abstract interfaces
%% and non-mutating operations on the nodes (see \secref{sec:interface-classes}).
%% Eevry node is constructed out of essential expressions, necessary to set up
%% its invariants.   For example, an \NodeClass{Identifier} node is constructed
%% out of the string that denotes the spelling of the identifier.  That string is
%% necessary and sufficient to determine whether two identifiers are the same or
%% not.

%% Consequently, IPR nodes

%% \subsubsection{Pros}

%% \subsubsection{Cons}

\subsection{Organization}
\label{sec:intro:organization}

The IPR library is organized into three header files:
\begin{enumerate}
\item The interface header file \texttt{<ipr/interface>}.  This header defines
  the abstract classes that serve as interface to the implementation classes.

\item The implementation header file \texttt{<ipr/impl>}.
  Implementations for abstract class in the interface header are found
  there.  Their names are derived from the interface my appending the
  suffix \texttt{\_impl}.

\item The input and ouput header file \texttt{<ipr/io>}.  This header provides
  functions for reading in memory IPR nodes externally represented in XPR
  syntax, and  writing out IPR nodes in the XPR syntax.
\end{enumerate}

\section{Interface Classes}
\label{sec:interface-classes}

All classes describing the interface of IPR are \emph{immutable} in the
sense that they support only \texttt{const} operations.  There is no way
programs using only the interface classes could alter the nodes.

A class of IPR nodes is said \emph{unified} if two nodes of that class have
equal values if and only if they have the same identity (as nodes).  Some
nodes naturally lead themselves to unification in the sense that they are
completely determined by their types and the argument list used to create
them.  Examples of such nodes are those that represent pointer-types,
reference-types or identifiers.  Other nodes, such as sequences, are first
created then ``filled up''.  Unification for such nodes involves some degree
of structural equality.

As stated in the introductory section of this paper, most of the IPR notions
are driven by the representation of declarations, with full type information.
Declarations involve types and expressions (as initializers).  C++ expressions
share similarity with C++ types in the sense that most of them are obtained as
the result of sub-components compositions through unary, binary or ternary
operators.  That observation is at the basis of the decision of viewing most
C++ entities as \emph{generalized expressions}, or simply expressions when the
context is clear.  In particular, types, statements and declarations are
generalized expressions.

\subsection{Structural interfaces}
\label{sec:interface:structure}

As observed above, there is a high degree of common structures between
expressions, types and statements.  Those commonality are captured in form of
unary, binary or ternary expressions, and rendered as the following
interfaceo templates:
\begin{Program}
         // -- Unary<> --
   template<class Cat = Expr, class Operand = Expr>
   struct Unary : Cat \{
      typedef Operand Arg_type;
      virtual const Operand& operand() const = 0;
   \};

         // -- Binary<> --
   template<class Cat = Expr, class First = Expr, class Second = Expr>
   struct Binary : Cat \{
      typedef First Arg1_type;
      typedef Second Arg2_type;
      virtual const First& first() const = 0;
      virtual const Second& second() const = 0;
   \};

         // -- Ternary<> --
   template<class Cat = Expr, class First = Expr,
            class Second = Expr, class Third = Expr>
   struct Ternary : Cat \{
      typedef First Arg1_type;
      typedef Second Arg2_type;
      typedef Third Arg3_type;
      virtual const First& first() const = 0;
      virtual const Second& second() const = 0;
      virtual const Third& third() const = 0;
   \};
\end{Program}

The first template parameter \code{Cat} indicates the kind of major categories
(e.g. plain nodes, expressions, statements or declarations) the node is a
member of.  The remaning template parameters indicate the type if
sub-components.   The actual node interfaces will define forwarding functions
(with more meaningful names) to the generic selectors.

\subsection{Universal base class for nodes}
\label{sec:interface:node}
\begin{figure}[htbp]
  \leavevmode
  \centering
  \begin{xy}
    \xymatrix @W=4pc @H=1pc @R=0pc @*[F-]{%
      *=<4pc,1pc>[F-]{\xyrel{Node}} & *{} & *{} \\
      *=<4pc,1pc>[F-]{\xycst{node\_id}}\\
      *=<4pc,1pc>[F-]{\xylabel{accept}}\\
    }
  \end{xy}
  \caption{The \cat{Node} interface}
  \label{fig:node.struct}
\end{figure}

C++ programs are represented in IPR as graphs, the nodes of which denote
(generalizations of) C++ constructs.  Any notion directly represented in IPR
is so as an object of class derived (either directly or indirectly) from class
\texttt{Node}.  An informal definition of a \texttt{Node} is anything
of potential interest while traversing graphs of program fragments
(through the Visitor Design Pattern~\cite{gamma}).  This class is the root
of the IPR class hierarchies.
\begin{Program}
  struct Node \{
      const int node_id;
      Node();
     virtual void accept(Visitor&) const = 0;
  \};
\end{Program}

Every node in the IPR representation has a unique identifier (an integer
value) assigned to it at its creation.  That identifier value is given by
the member \code{Node::node\_id}.  An alternative would have been to use
the node's address as its unique identifier, but using an identifier
independent of
the address space provides good support for persistency.  It also means that
we can store nodes in associative containers and use their identifiers as
keys, at a relatively efficient and portable fashion.

\subsection{Comments in programs}
\label{sec:interface:comment}
\begin{figure}[htbp]
  \leavevmode
  \centering
  \begin{xy}
    \xymatrix @W=4pc @H=1pc @R=0pc @*[F-]{%
      *=<4pc,1pc>[F-]{\xyrel{Comment}} & *{} & *{} \\
      *=<4pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{text}} [rr]
      \restore
      & *{} &
      *=<7pc,1pc>{\txt{\cat{std::string}}}
    }
  \end{xy}
  \caption{The \cat{Comment} interface}
  \label{fig:comment.struct}
\end{figure}

A comment in C++ programs (be they written in C- or BCPL-style) are
represented as unary node, the operand of which is the character stream that
makes the comment:
\begin{Program}
   struct Comment : Unary<Node, std::string> \{
      const std::string& text() const \{ return operand(); \}
   \};
\end{Program}

\subsection{Annotations}
\label{sec:interface:annotations}
\begin{figure}[htbp]
  \leavevmode
  \centering
  \begin{xy}
    \xymatrix @W=5pc @H=1pc @R=0pc @*[F-] {%
      *=<5pc,1pc>[F-]{\xyrel{Annotation}} & *{} & *{} \\
      *=<5pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{name}} [rr]
      \restore
      & *{} &
      *=<7pc,1pc>{\txt{\cat{std::string}}} \\
      *=<5pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{value}} [rr]
      \restore
      & *{} &
      *=<5pc,1pc>{\txt{\cat{Literal}}}
    }
  \end{xy}
  \caption{\cat{Annotation} interface}
  \label{fig:annotation.struct}
\end{figure}

The external and internal representations of C++ programs allow for
annotations on statements.  Annotations mostly represent informations
not understood by IPR.  They are pairs of identifier and literal.
\begin{Program}
   struct Annotation : Binary<Node, std::string, Literal> \{
      const std::string& name() const \{ return first(); \}
      const Literal& value() const    \{ return second(); \}
   \};
\end{Program}

The exact interpretation of an annotation is dependent on the tool
that uses the IPR library.  Only statements (and therefore declarations)
can be directly annotated.

\subsection{Regions of program text}
\label{sec:interface:region}

Declarations appear inside regions of program texts.  Regions contribute to
determine validity of name use, objects lifetime, and lexical
characterizations of program fragments.  Regions nest.  Consequently, every
region but the global has a parent region.
\begin{Program}
   struct Region : Node \{
      typedef std::pair<Unit_location, Unit_location> Location_span;
      virtual const Location_span& span() const = 0;
      virtual const Region& enclosing() const = 0;
      virtual const Scope& bindings() const = 0;
      virtual const Expr& owner() const = 0;
   \};
\end{Program}
Regions can be delimitated so that they correspond to lexical extent of
function or class definitions.  A region has an owner, \ie{} C++ entities they
are attached to.  Finally, all declarations appearing in a given region form a
scope, available through  \xyiprop{Region::bindings}.
\begin{figure}[htbp]
  \leavevmode
  \centering
  \begin{xy}
    \xymatrix @W=4pc @H=1.5pc @R=0pc @*[F-] {%
      *=<4pc,1.5pc>[F-]{\xyrel{Region}} & *{} & *{} \\
      *=<4pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{span}} [rr]
      \restore
      & *{} &
      *=<7pc,1pc>{\txt{\cat{Location\_span}}} \\
      *=<4pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{enclosing}} [rr]
      \restore
      & *{} &
      *=<4pc,1pc>{\txt{\cat{Region}}}\\
      *=<4pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{bindings}} [rr]
      \restore
      & *{} &
      *=<4pc,1pc>{\txt{\cat{Scope}}}\\
      *=<4pc,1pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{owner}} [rr]
      \restore
      & *{} &
      *=<4pc,1pc>{\txt{\cat{Expr}}}
    }
  \end{xy}
  \caption{\cat{Region} interface}
  \label{fig:region.struct}
\end{figure}

\subsection{Program unit}
\label{sec:interface:unit}

A unit is the sequence of toplevel declarations in a transltaion or
instantiation unit.
\begin{Program}
   struct Unit : Node \{
      virtual const Namespace& global_namespace() const = 0;
      virtual const Type& Void() const = 0;
      virtual const Type& Bool() const = 0;
      virtual const Type& Char() const = 0;
      virtual const Type& Signed_char() const = 0;
      virtual const Type& Unsigned_char() const = 0;
      virtual const Type& Wchar_t() const = 0;
      virtual const Type& Short() const = 0;
      virtual const Type& Unsigned_short() const = 0;
      virtual const Type& Int() const = 0;
      virtual const Type& Unsigned_int() const = 0;
      virtual const Type& Long() const = 0;
      virtual const Type& Unsigned_long() const = 0;
      virtual const Type& Long_long() const = 0;
      virtual const Type& Unsigned_long_long() const = 0;
      virtual const Type& Float() const = 0;
      virtual const Type& Double() const = 0;
      virtual const Type& Long_double() const = 0;
      virtual const Expr& null_expr() const = 0;
   \};
\end{Program}
It provides access to C++ fundamental types.

\subsection{Generalized expressions}
\label{sec:interface:expr}

As explained earlier, most C++ notions are represented in IPR as generalized
expressions.  All IPR expressions are typed. For instance, a declatarion
\begin{Program}
   struct Expr : Node \{
      virtual const Type& type() const = 0;
   \};
\end{Program}
obviously has a type (which is the type specified in the declaration).  In
particular, a template declaration has a type (as opposed to Standard C++).
A type in turn has a type, as explained previously.

\subsection{Overload sets}
\label{sec:interface:overload}

The result of looking up the totallity of declarations for a name in a given
scope is an overload set.  An overload set is further partitioned into subsets
of declarations or redeclarations with same type.
\begin{Program}
   struct Overload : Sequence<Decl>, Expr \{
      using Sequence<Decl>::operator[];
      virtual const Sequence<Decl>& operator[](const Type&) const = 0;
   \};
\end{Program}
An overload set is an expression, therefore has a type.  The type of an
overload set is a Product type, that accounts for the types of all master
declarations.

Selecting a particular member of an overload set, based on its type is
supported through the subscription-by-type operation.  The result of that
operation is the master declaration with that type.

\subsection{Interface for scopes}
\label{sec:interface:scope}

There is only one interface class, \texttt{Scope}, that represents the variety
of scopes available in a C++ programs (function scope, function prototype
scope, local scope, class scope, namespace scope).

The following are general operations supported by all scope nodes.
\begin{description}
\item[\texttt{const Type\& owner(const Scope scope\&)}]
  Returns a \const{} reference to the \texttt{Type} that defines
  \texttt{scope}.  Any scope is  associated with a given type for which it
  represents the sequence of associated members or values.

\item[\texttt{Scope::operator[](const Name\& name) const}]
  Returns a \const{} reference to an \texttt{Overload} that contains all
  the master declarations of \texttt{name} (in the calling \texttt{Scope}
  object).
  This set has null size if no declaration is found. The name look up
  considered here is the \emph{lexical} name lookup.
\end{description}

\texttt{Scope}s are visitable, they have an \texttt{accept()} member function
that takes a reference to any vistor whose type derives from

\subsection{Naming entities}

\subsubsection{\texttt{Identifier}}
\label{sec:interface:identifier}
An \emph{identifier} in IPR is anything that Standard C++ defines as
identifier, although the IPR library does not make any special enforcement.
%% \begin{displaymath}
%%   \xyrel{Identifier}: \cat{Alphanumeric}\longrightarrow\cat{Identifier}.
%% \end{displaymath}
The string that serves to construct an \cat{Identifier} is given by the
operation \iprop{string()}:
%% \begin{displaymath}
%%   \forall s \in\cat{Alphanumeric}\qquad
%%   \iprop{string}\of{\xyrel{Identifier}\of{s}} = s.
%% \end{displaymath}

Identifiers are expressions, and do belong to a given category.  That category
is the value of the operation \iprop{type()}.  Since interpretations of
identifiers depend on the context of use, the type of an identifier is a
\cat{Decltype} whose operand is the identifier in question.
\begin{figure}[htbp]
  \leavevmode
  \centering
  \begin{xy}
    \xymatrix @W=5pc @H=1pc @R=0pc @*[F-] {%
      {\xyrel{Identifier}} & *{} &
      {\xyrel{Delctype}} \\
      *+<5pc,2pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{type}} [rr]
      \restore
      & *{} &
      *+<5pc,2pc>[F-]{\bullet}
      \save
      * {} \ar`r[u] +/r4pc/^{\xylabel{expr}}
      `[u] +/u2pc/
      `[ll][llu]
      \restore
      \\
      *+<5pc,2pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{string}} [rr]
      \restore
      & *{} &
      *+=<5pc,2pc>[F-:<4pt>]{\txt{\cat{std::string}}}
    }
  \end{xy}
  \caption{\cat{Identifier} interface}
  \label{fig:identifier.struct}
\end{figure}
The IPR interface to the category \cat{Identifier} of identifiers is
implemented by the class \code{Identifier}:
\begin{Program}
   struct Identifier : Unary<Name, std::string> \{
      const std::string& string() const \{ return operand(); \}
   \};
\end{Program}

\subsubsection{\texttt{Operator}}
\label{sec:interface:operator}
An IPR \emph{operator name} is any Standard C++ operator name of the form
\code{operator @}, where \code{@} is a member of \cat{OperatorName} (see
table ???).
%% \begin{displaymath}
%%   \xyrel{Operator}:\cat{OperatorName}\longrightarrow\cat{Operator}.
%% \end{displaymath}
Similar to an \cat{Identifier}, the string that served to construct
an \cat{Operator} is given by the operation \iprop{opname}:
%% \begin{displaymath}
%%   \forall s \in\cat{OperatorName}\qquad
%%   \iprop{opname}\of{\xyrel{Operator}\of{s}} = s.
%% \end{displaymath}

Also, similar to an \cat{Identifier}, an \cat{Operator} supports the
\iprop{type} operation.
\begin{figure}[htbp]
  \leavevmode
  \centering
  \begin{xy}
    \xymatrix @W=5pc @H=1pc @R=0pc @*[F-] {%
      {\xyrel{Operator}} & *{} &
      {\xyrel{Delctype}} \\
      *+<5pc,2pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{type}} [rr]
      \restore
      & *{} &
      *+<5pc,2pc>[F-]{\bullet}
      \save
      * {} \ar`r[u] +/r4pc/^{\xylabel{expr}}
      `[u] +/u2pc/
      `[ll][llu]
      \restore
      \\
      *+<5pc,2pc>[F-]{\bullet}
      \save
      * {} \ar ^{\xylabel{opname}} [rr]
      \restore
      & *{} &
      *+=<5pc,2pc>[F-:<4pt>]{\txt{\cat{std::string}}}
    }
  \end{xy}
  \caption{\cat{Operator} interface}
  \label{fig:operator.struct}
\end{figure}
The value of that operation is a \cat{Decltype} whose
operand is the \cat{Operator}.
The IPR interface to the operator name category \cat{Operator} is implemented
by the class \code{Operator}:
\begin{Program}
   struct Operator : Unary<Name, std::string> \{
      const std::string& opname() const \{ return operand(); \}
   \};
\end{Program}

\subsubsection{\texttt{Conversion}}
\label{sec:interface:conversion}
A \emph{conversion} name is any name made out of \texttt{operator} and
a type.  Given
%% \begin{displaymath}
%%   \rel{Conversion}:\cat{Type}\longrightarrow\cat{Name}
%% \end{displaymath}
the following holds:
%% \begin{displaymath}
%%   \forall t\in\cat{Type}\qquad
%%   \mathit{target}\of{\rel{Conversion}\of{t}} = t.
%% \end{displaymath}

The IPR interface to \cat{Conversion} is
\begin{Program}
   struct Conversion : Unary<Name, Type> \{
      const Type& target() const \{ return operand(); \}
   \};
\end{Program}
\begin{description}
\item[\texttt{Conversion::target() const}] The type this conversion function
  converts to.
\end{description}

\subsection{Expressions}

Nearly everyting is an expression in IPR.  An \emph{expression} is understood
as the specification of an operator and arguments for a computation.  The
operator need not be alsways explicitly spelled out.

The various categories of expressions are described in detail in subsequent
sections.  The interface to this notion is given by
\begin{Program}
   struct Expr : Node \{
      virtual const Type& type() const = 0;
   \};
\end{Program}
Thus, every expression node supports the \texttt{type()} and
\texttt{annotation()} operations:
\begin{description}
\item[\texttt{Expr::type() const}] The IPR node that represent the type of
  this expression.
\item[\texttt{Expr::annotation() const}] The sequence of annotations made to
  this expression.
\end{description}

\subsection{Literals}

%% \begin{displaymath}
%%   \rel{Literal} : \cat{String} \times \cat{Type} \longrightarrow
%%   \cat{Expr}
%% \end{displaymath}

%% \begin{align*}
%%   \forall s\in\cat{String},\, \forall t\in\cat{Type}\qquad
%%   &\mathit{string}\of{\rel{Literal}\of{s,\, t}} = s\\
%%   &\mathit{type}\of{\rel{Literal}\of{s,\, t}} = t
%% \end{align*}

\begin{Program}
   struct Literal : Binary<Expr, Type, std::string> \{
      const Type& type() const \{ return first(); \}
      const std::string& string() const \{ return second(); \}
   \};
\end{Program}

\begin{description}
\item[\texttt{Literal::string()}]
\end{description}

\subsection{Types in IPR}
\label{sec:interface:types}

The variety of C++ types are represented in IPR.  The abstract class
\texttt{Type} serves as a base class of that hierarchy.  A type in IPR is a
generalized expression, and therefore derives from the abstract class
\texttt{Expr}.

\subsubsection{Reference type}
%% \begin{gather*}
%%   \rel{Reference} : \cat{Type} \longrightarrow \cat{Type}\\
%%   \forall t\in\cat{Type}\qquad
%%   \mathit{refers\_to}\of{\rel{Reference}\of{t}} = t
%% \end{gather*}

\begin{Program}
  struct Reference : Unary<Type, Type> \{
    const Type& refers_to() const \{ return operand(); \}
  \};
\end{Program}

\subsubsection{Function type}
%% \begin{displaymath}
%%   \rel{Function} : \cat{Signature} \times \cat{Type} \times
%%   \cat{Sequence_{Type}} \longrightarrow \cat{Type}
%% \end{displaymath}
%% \begin{align*}
%%   \forall s\in \cat{Signature},\, \forall t\in\cat{Type},\,
%%   \forall e\in\cat{Sequence_{Type}}\qquad
%%   &\mathit{signature}\of{\rel{Function}\of{s,\, t,\, e}} = s\\
%%   &\mathit{target}\of{\rel{Function}\of{s,\, t,\, e}} = t\\
%%   &\mathit{throws}\of{\rel{Function}\of{s,\, t,\, e}} = e\\
%% \end{align*}

\begin{Program}
   struct Function : Ternary<Type, Product, Type, Type> \{
      const Product& signature() const \{ return first(); \}
      const Type& target() const \{ return second(); \}
      const Type& throws() const \{ return third(); \}
   \};
\end{Program}

\begin{description}
\item[\texttt{Function::signature() const}]
\item[\texttt{Function::target() const}]
\item[\texttt{Function::throws() const}]
\end{description}

\subsubsection{Pointer type}
%% \begin{gather*}
%%   \rel{Pointer} : \cat{Type} \longrightarrow \cat{Type}\\
%%   \forall t\in \cat{Type}\qquad
%%   \mathit{points\_to}\of{\rel{Pointer}\of{t}} = t
%% \end{gather*}

\begin{Program}
   struct Pointer : Unary<Type, Type> \{
      const Type& points_to() const \{ return operand(); \}
   \};
\end{Program}
\begin{description}
\item[\texttt{Pointer::points\_to() const}]
\end{description}

\subsubsection{Array type}
%% \begin{gather*}
%%   \rel{Array} : \cat{Object\_type}\times\cat{Expr}
%%   \longrightarrow \cat{Object\_type}\\
%%   \forall t\in\cat{Object\_type},\,\forall b\in\cat{Expr}\\
%%   \mathit{element\_type}\of{\rel{Array}\of{t,\, b}} = t\\
%%   \mathit{bound}\of{\rel{Array}\of{t,\, b}} = b\\
%% \end{gather*}

\begin{Program}
   struct Array : Binary<Type, Type, Expr> \{
      const Type& element_type() const \{ return first(); \}
      const Expr& bound() const        \{ return second(); \}
   \};
\end{Program}

\begin{description}
\item[\texttt{Array::element\_type() const}]
\item[\texttt{Array::bound() const}]
\end{description}

\subsubsection{User-defined types}
%% \begin{gather*}
%%   \rel{Udt} : \cat{String}\times \cat{Scope} \times \cat{Scope}
%%   \longrightarrow \cat{Type}\\
%%   \rel{Class} =
%%   \rel{Udt}\of{\rel{Class},\, \bullet,\,\bullet}\\
%%   \rel{Union} =
%%   \rel{Udt}\of{\rel{Union},\, \bullet,\,\bullet}\\
%%   \rel{Enum} =
%%   \rel{Udt}\of{\rel{Enum},\, \bullet,\,\bullet}\\
%%   \rel{Namespace} =
%%   \rel{Udt}\of{\rel{Namespace},\, \bullet,\,\bullet}\\
%% \end{gather*}

%% \begin{align*}
%%   \forall b\in\cat{Scope},\,\forall m\in\cat{Scope}\qquad
%%   &\mathit{bases}\of{\rel{User\_defined\_type}\of{\bullet,\, b, m}} = b\\
%%   &\mathit{members}\of{\rel{User\_defined\_type}\of{\bullet,\, b, m}} = m\\
%% \end{align*}

\begin{Program}
   struct Udt : Type \{
      virtual const Scope& scope() const = 0;
   \};

   struct Namespace : Udt \{
      const Sequence<Decl>& members() const \{ return scope().members(); \}
   \};

   struct Class : Udt \{
      const Sequence<Decl>& members() const \{ return scope().members(); \}
      virtual const Sequence<Base_type>& bases() const = 0;
      virtual const Scope& base_scope() const = 0;
   \};

   struct Union : Udt \{
      const Sequence<Decl>& members() const \{ return scope().members(); \}
   \};

   struct Enum : Udt \{
      virtual const Sequence<Enumerator>& members() const = 0;
   \};
\end{Program}

\subsection{Unary expressions}
\label{sec:interface:unary-expr}

\subsubsection{Incrementation}
%% \begin{gather*}
%%   \rel{Pre\_increment}:\cat{Expr}\longrightarrow\cat{Expr}\\
%%   \rel{Post\_increment}:\cat{Expr}\longrightarrow\cat{Expr}
%% \end{gather*}

\subsubsection{Decrementation}
%% \begin{gather*}
%%   \rel{Pre\_decrement}:\cat{Expr}\longrightarrow\cat{Expr}\\
%%   \rel{Post\_decrement}:\cat{Expr}\longrightarrow\cat{Expr}
%% \end{gather*}

\subsubsection{Conversions}
%% \begin{gather*}
%%   \rel{Dynamic\_cast}:\cat{Expr}\times\cat{Type}\longrightarrow\cat{Expr}\\
%%   \rel{Static\_cast}:\cat{Expr}\times\cat{Type}\longrightarrow\cat{Expr}\\
%%   \rel{Reinterpret\_cast}:\cat{Expr}\times\cat{Type}
%%   \longrightarrow\cat{Expr}\\
%%   \rel{Const\_cast}:\cat{Expr}\times\cat{Type}\longrightarrow\cat{Expr}\\
%%   \rel{Cast}:\cat{Expr}\times\cat{Type}\longrightarrow\cat{Expr}
%% \end{gather*}

\subsubsection{Type identification}

A type identification comes in two flavors
%% \begin{gather*}
%%   \rel{Expr\_typeid} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Type\_typeid} : \cat{Type} \longrightarrow \cat{Expr}
%% \end{gather*}

\subsubsection{Size of object representation}
%% \begin{gather*}
%%   \rel{Expr\_sizeof} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Type\_sizeof} : \cat{Type} \longrightarrow \cat{Expr}
%% \end{gather*}

\subsubsection{Dereferencing}
%% \begin{displaymath}
%%   \rel{Deref}: \cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Taking the address of an object}
%% \begin{displaymath}
%%   \rel{Address} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Unary plus}
%% \begin{displaymath}
%%   \rel{Unary\_plus} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Negation}
%% \begin{gather*}
%%   \rel{Negate} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Not} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{gather*}

\subsubsection{Complement}
%% \begin{displaymath}
%%   \rel{Complement} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Deletion}
%% \begin{gather*}
%%   \rel{Delete} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Array\_delete} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{gather*}

\subsection{Binary expressions}
\label{sec:interface:binary-expr}

\subsubsection{Multiplicative expressions}
%% \begin{gather*}
%%   \rel{Mul} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Div} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Modulo} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%% \end{gather*}

\subsubsection{Additive expressions}
%% \begin{gather*}
%%   \rel{Add} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Sub} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%% \end{gather*}

\subsubsection{Logical expressions}
%% \begin{gather*}
%%   \rel{Less} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Greater} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Equal} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Less\_equal} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Greater\_equal} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Not\_equal} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{And} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Or} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%% \end{gather*}

\subsubsection{Bits arithmetic}
%% \begin{gather*}
%%   \rel{Bit\_and} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Bit\_xor} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Bit\_or} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Shift\_left} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Shift\_right} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}
%% \end{gather*}

\subsubsection{Member selection}
%% \begin{gather*}
%%   \rel{Dot\_select} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Dot\_star} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Arrow\_select} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Arrow\_star} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%%   \rel{Scope\_select} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}\\
%% \end{gather*}

\subsubsection{Expression sequencing}
%% \begin{displaymath}
%%   \rel{Comma} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Assignment}
%% \begin{displaymath}
%%   \rel{Assign} : \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsection{Expressions with variable number of arguments}
\label{sec:interface:var-args-expr}

\subsubsection{Function call}
%% \begin{displaymath}
%%   \rel{Call} : \cat{Expr} \times \cat{Sequence}
%%   \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Data construction}
%% \begin{displaymath}
%%   \rel{Object\_construction} : \cat{Type} \times \cat{Sequence}
%%   \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsection{Statements}

\subsubsection{Labeled statements}

%% \begin{displaymath}
%%   \rel{Labeled\_stmt} : \cat{Expr}\times\cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\subsubsection{Expression statements}

\begin{Program}
   struct Expr_stmt : Stmt \{
      virtual const Expr& expr() const = 0;
   \};
\end{Program}

\begin{Program}
   struct Labeled_stmt : Stmt \{
      virtual const Expr& label() const = 0;
      virtual const Expr& stmt() const = 0;
   \};
\end{Program}

\subsubsection{Blocks}

%% \begin{displaymath}
%%   \rel{Block} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\begin{Program}
   struct Block : Stmt \{
      virtual const Scope& members() const = 0;
      virtual const Sequence<Expr>& stmts() const = 0;
      virtual const Sequence<Handler>& handlers() const = 0;
   \};
\end{Program}

\subsubsection{Ctor bodies}

%% \begin{displaymath}
%%   \rel{Function\_body} : \cat{Sequence_{Expr}} \times
%%   \cat{Block} \longrightarrow \cat{Expr}
%% \end{displaymath}

\begin{Program}
   struct Ctor_body : Stmt \{
      virtual const Expr_list& inits() const = 0;
      virtual const Block& block() const = 0;
   \};
\end{Program}

\subsubsection{Selection statements}

%% \begin{gather*}
%%   \rel{If\_then} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{If\_then\_else} : \cat{Expr} \times \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}
%% \end{gather*}

\begin{Program}
   struct If_then : Stmt \{
      virtual const Expr& condition() const = 0;
      virtual const Expr& then_stmt() const = 0;
   \};

   struct If_then_else : Stmt \{
      virtual const Expr& condition() const = 0;
      virtual const Expr& then_stmt() const = 0;
      virtual const Expr& else_stmt() const = 0;
   \};
\end{Program}

%% \begin{displaymath}
%%   \rel{Switch} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}
%% \end{displaymath}

\begin{Program}
   struct Switch : Stmt {
      virtual const Expr& condition() const = 0;
      virtual const Expr& body() const = 0;
   };
\end{Program}

\subsubsection{Iteration iterations}

%% \begin{gather*}
%%   \rel{While} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Do} : \cat{Expr} \times \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{For} : \cat{Expr} \times \cat{Expr} \times \cat{Expr} \times \cat{Expr}
%%   \longrightarrow \cat{Expr}
%% \end{gather*}

\begin{Program}
   struct While : Stmt \{
      virtual const Expr& condition() const = 0;
      virtual const Expr& body() const = 0;
   \};

   struct Do : Stmt \{
      virtual const Expr& condition() const = 0;
      virtual const Expr& body() const = 0;
   \};

   struct For : Stmt \{
      virtual const Expr& initializer() const = 0;
      virtual const Expr& condition() const = 0;
      virtual const Expr& increment() const = 0;
      virtual const Expr& body() const = 0;
   \};
\end{Program}

\subsubsection{Jump statements}

%% \begin{gather*}
%%   \rel{Break} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Continue} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Goto} : \cat{Expr} \longrightarrow \cat{Expr}\\
%%   \rel{Return} : \cat{Expr} \longrightarrow \cat{Expr}
%% \end{gather*}

\begin{Program}
   struct Break : Stmt \{
      virtual const Expr& from() const = 0;
   \};

   struct Continue : Stmt \{
      virtual const Expr& iteration() const = 0;
   \};

   struct Goto: Stmt \{
      virtual const Expr& target() const = 0;
   \};

   struct Return : Stmt \{
      virtual const Expr& value() const = 0;
      const Type& type() const  { return value().type(); }
   \};
\end{Program}

\subsubsection{Exception handlers}

\begin{Program}
   struct Handler : Stmt \{
      virtual const Decl& exception() const = 0;
      virtual const Block& body() const = 0;
   \};
\end{Program}

\subsection{Declarations}

\begin{Program}
   struct Decl : Stmt \{
      enum Specifier \{
         None = 0,
         Auto       = 1 << 0,
         Register   = 1 << 1,
         Static     = 1 << 2,
         Extern     = 1 << 3,
         Mutable    = 1 << 4,
         StorageClass  = Auto | Register | Static | Extern | Mutable,

         Inline     = 1 << 5,
         Virtual    = 1 << 6,
         Explicit   = 1 << 7,
         Pure       = 1 << 8,
         FunctionSpecifier = Inline | Virtual | Explicit | Pure,

         Friend     = 1 << 9,
         Typedef    = 1 << 10,

         Public     = 1 << 11,
         Protected  = 1 << 12,
         Private    = 1 << 13,
         AccessProtection = Public | Protected | Private
      \};

      virtual Specifier specifiers() const = 0;
      virtual const Name& name() const = 0;
      virtual const Scope& scope() const = 0;

      virtual bool has_initializer() const = 0;
      virtual const Expr& initializer() const = 0;

      const Sequence<Decl>& decl_set() const
      \{ return scope()[name()][type()]; \}
      const Decl& master() const \{ return *decl_set().begin(); \}
   \};
\end{Program}

A declaration is a statement. It usually introduces a name in a given scope
and attributes for its interpretation: (a) a type; (b) a set of specifiers for
access or storage; and (b) an optional initializer.

\subsubsection{Declaration specifiers}

\paragraph{Storage class specifiers}

\paragraph{Function specifiers}

\paragraph{Access control and friendship}

\subsubsection{Variable declarations}
\begin{Program}
   struct Var : Decl \{
   \};
\end{Program}

\subsubsection{Data member declarations}

\begin{Program}
   struct Field : Decl \{
   \};

   struct Bit_field : Decl \{
      virtual const Expr& size() const = 0;
   \};
\end{Program}

\subsubsection{Parameter declarations}
\begin{Program}
   struct Parameter : Decl \{
      virtual int position() const = 0;
      const Expr& default_value() const { return initializer(); }
   \};
\end{Program}

\subsubsection{Function declarations}

\begin{Program}
   struct Fun_decl : Decl \{
      virtual const Type& target() const = 0;
      virtual const Parameter_list& parameters() const = 0;
      virtual const Type& throws() const = 0;
   \};
\end{Program}

\paragraph{Constructors}
\begin{Program}
   struct Constructor : Fun_decl \{
      const Name& name() const \{ return membership().name(); \}
      const Type& target() const \{ return membership(); \}

      virtual const Type& membership() const = 0;
   \};
\end{Program}

\paragraph{Destructors}

\begin{Program}
   struct Destructor : Fun_decl \{
      virtual const Type& membership() const = 0;
   \};
\end{Program}

\subsubsection{Alias declarations}
\begin{Program}
   struct Alias : Decl \{
   \};
\end{Program}

\subsubsection{Base-type declarations}
\begin{Program}
   struct Base_type : Decl \{
      const Name& name() const \{ return type().name(); \}
   \};
\end{Program}

\subsubsection{Enumerator declarations}

\begin{Program}
   struct Enumerator : Decl \{
      const Type& type() const \{ return membership(); \}
      virtual const Enum& membership() const = 0;
   \};
\end{Program}

\subsubsection{Type declarations}

\begin{Program}
   struct Type_decl : Decl \{
   \};
\end{Program}

\subsection{Traversing graphs:  Visitors}
\begin{Program}
   struct Visitor \{
      virtual void visit(const Node&) = 0;
      virtual void visit(const Annotation&);

      virtual void visit(const Expr&) = 0;

      virtual void visit(const Name&) = 0;
      virtual void visit(const Identifier&);
      virtual void visit(const Operator&);
      virtual void visit(const Conversion&);
      virtual void visit(const Type_id&);

      virtual void visit(const Type&) = 0;
      virtual void visit(const Array&);
      virtual void visit(const Class&);
      virtual void visit(const Enum&);
      virtual void visit(const Expr_as_type&);
      virtual void visit(const Function&);
      virtual void visit(const Namespace&);
      virtual void visit(const Pointer&);
      virtual void visit(const Product&);
      virtual void visit(const Reference&);
      virtual void visit(const Template&);
      virtual void visit(const Union&);
      virtual void visit(const Udt&);

      virtual void visit(const Expr_list&);
      virtual void visit(const Overload&);
      virtual void visit(const Scope&);

      virtual void visit(const Address&);
      virtual void visit(const Array_delete&);
      virtual void visit(const Complement&);
      virtual void visit(const Delete&);
      virtual void visit(const Deref&);
      virtual void visit(const Expr_sizeof&);
      virtual void visit(const Expr_stmt&);
      virtual void visit(const Expr_typeid&);
      virtual void visit(const Label&);
      virtual void visit(const Negate&);
      virtual void visit(const Not&);
      virtual void visit(const Post_decrement&);
      virtual void visit(const Post_increment&);
      virtual void visit(const Pre_decrement&);
      virtual void visit(const Pre_increment&);
      virtual void visit(const Throw&);
      virtual void visit(const Type_sizeof&);
      virtual void visit(const Type_typeid&);
      virtual void visit(const Unary_plus&);

      virtual void visit(const Add&);
      virtual void visit(const Add_assign&);
      virtual void visit(const And&);
      virtual void visit(const Array_ref&);
      virtual void visit(const Arrow_select&);
      virtual void visit(const Arrow_star&);
      virtual void visit(const Assign&);
      virtual void visit(const Bitand&);
      virtual void visit(const Bitand_assign&);
      virtual void visit(const Bitor&);
      virtual void visit(const Bitor_assign&);
      virtual void visit(const Bitxor&);
      virtual void visit(const Bitxor_assign&);
      virtual void visit(const C_cast&);
      virtual void visit(const Call&);
      virtual void visit(const Comma&);
      virtual void visit(const Const_cast&);
      virtual void visit(const Div&);
      virtual void visit(const Div_assign&);
      virtual void visit(const Dot_select&);
      virtual void visit(const Dot_star&);
      virtual void visit(const Dynamic_cast&);
      virtual void visit(const Equal&);
      virtual void visit(const Greater&);
      virtual void visit(const Greater_equal&);
      virtual void visit(const Less&);
      virtual void visit(const Less_equal&);
      virtual void visit(const Literal&);
      virtual void visit(const Member_init&);
      virtual void visit(const Modulo&);
      virtual void visit(const Modulo_assign&);
      virtual void visit(const Mul&);
      virtual void visit(const Mul_assign&);
      virtual void visit(const Not_equal&);
      virtual void visit(const Object_construction&);
      virtual void visit(const Or&);
      virtual void visit(const Reinterpret_cast&);
      virtual void visit(const Scope_ref&);
      virtual void visit(const Shift_left&);
      virtual void visit(const Shift_left_assign&);
      virtual void visit(const Shift_right&);
      virtual void visit(const Shift_right_assign&);
      virtual void visit(const Specialization&);
      virtual void visit(const Static_cast&);
      virtual void visit(const Sub&);
      virtual void visit(const Sub_assign&);

      virtual void visit(const Conditional&);
      virtual void visit(const New&);

      virtual void visit(const Stmt&) = 0;
      virtual void visit(const Labeled_stmt&);
      virtual void visit(const Block&);
      virtual void visit(const Ctor_body&);
      virtual void visit(const If_then&);
      virtual void visit(const If_then_else&);
      virtual void visit(const Switch&);
      virtual void visit(const While&);
      virtual void visit(const Do&);
      virtual void visit(const For&);
      virtual void visit(const Break&);
      virtual void visit(const Continue&);
      virtual void visit(const Goto&);
      virtual void visit(const Return&);
      virtual void visit(const Handler&);

      virtual void visit(const Decl&) = 0;
      virtual void visit(const Alias&);
      virtual void visit(const Base_type&);
      virtual void visit(const Parameter&);
      virtual void visit(const Parameter_list&);
      virtual void visit(const Var&);
      virtual void visit(const Field&);
      virtual void visit(const Bit_field&);
      virtual void visit(const Fun_decl&);
      virtual void visit(const Constructor&);
      virtual void visit(const Destructor&);
      virtual void visit(const Type_decl&);
   \};
\end{Program}

\section{Implementation Classes}
\label{sec:impl}

Every abstract class in the interface class hierarchy has a corresponding
implementation class, named after that interface and with the suffix
\texttt{Impl}. Those implementations classes often supports
non-\texttt{const} operations too.  Every implementation class provide
an overriding implementation for the visitor hook
\texttt{Node::accept()} that transfer control to the appropriate overriding
member function of \texttt{Visitor::visit()}

There is only one instance of \texttt{std::string} for any given text string
that might be hold in any IPR node (e.g. by names).

\subsection{Implementation classes for names}

The four kinds of names \textit{identifier}, \textit{operator name},
\textit{conversion-function name}  and \textit{template instantiation name}
are respectively implemented by \texttt{impl::Identifer},
\texttt{impl::Operator}, \texttt{impl::Conversion} and
\texttt{impl::Specialization}.  They all derive from instantiations of the
parameterized implementation class \texttt{impl::Name<>}.  The later
is parameterized by the interface

\subsubsection{\texttt{impl::Identifier}}

\subsubsection{\texttt{impl::Operator}}

\subsubsection{\texttt{impl::Conversion}}

\section{XPR grammars}
\label{sec:xpr-grammar}

XPR essentially retains C++'s syntax for expressions.  The differences appear
mainly in the declaration syntax where XPR aims for a linear notation.
\subsection{Lexical conventions}
\label{sec:xpr-grammar:lexical-convention}

\subsubsection{Literals}

XPR retains C~\cite{iso99} and C++~\cite{iso03}'s spelling for literals
\begin{Program}

\end{Program}

\bibliographystyle{amsplain}
\bibliography{ipr}

\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:


text:
This repository is no longer maintained.
View https://github.com/physikerwelt/mathsearch-backend-basex for the latest version.

fse-ntcir11-wmc-basex
=====================

Code used for the BaseX run of the FSE team at the NTCIR-11 Math Wikipedia Subtask

## Obtain the data
The dataset is availible from

http://demo.formulasearchengine.com/images/NTCIR-11-Wikipedia-Math-MWS-Dump.zip

and can be referenced via DOI 10.13140/2.1.1374.9445

## Obtain the queries
The queries are included in this repository and can be downloaded from

http://demo.formulasearchengine.com/images/NTCIR11-Math-mathQueries-participants.xml

The queries can be referenced via DOI 10.13140/2.1.1618.6564

## Steps performed for the submission
```
mkdir /tmp/baseX
cd /tmp/baseX
git clone https://github.com/TU-Berlin/fse-ntcir11-wmc-basex .
mvn install
mkdir data
cd data
wget http://demo.formulasearchengine.com/images/NTCIR-11-Wikipedia-Math-MWS-Dump.zip
unzip NTCIR-11-Wikipedia-Math-MWS-Dump.zip
cd ..
wget http://demo.formulasearchengine.com/images/NTCIR11-Math-mathQueries-participants.xml
cp target/basex-backend-0.0.1-SNAPSHOT-jar-with-dependencies.jar .
time java -Xmx12G -jar basex-backend-0.0.1-SNAPSHOT-jar-with-dependencies.jar -d /tmp/baseX/data -q NTCIR11-Math-mathQueries-participants.xml -o ./results.csv -c
```

* Overall runtime 8min 24seconds.
* Submitted to http://ntcir11-wmc.nii.ac.jp/index.php/Special:MathUpload as run 94.
* Up to 96% correct.
* 92% according to the new formula centric match.
* No errors during import.


text:
<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: google/pubsub/v1/pubsub.proto

namespace Google\Cloud\PubSub\V1;

use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;

/**
 * Request for the UpdateSubscription method.
 *
 * Generated from protobuf message google.pubsub.v1.UpdateSubscriptionRequest
 */
class UpdateSubscriptionRequest extends \Google\Protobuf\Internal\Message
{
    /**
     * Required. The updated subscription object.
     *
     * Generated from protobuf field .google.pubsub.v1.Subscription subscription = 1 [(.google.api.field_behavior) = REQUIRED];
     */
    private $subscription = null;
    /**
     * Required. Indicates which fields in the provided subscription to update.
     * Must be specified and non-empty.
     *
     * Generated from protobuf field .google.protobuf.FieldMask update_mask = 2 [(.google.api.field_behavior) = REQUIRED];
     */
    private $update_mask = null;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type \Google\Cloud\PubSub\V1\Subscription $subscription
     *           Required. The updated subscription object.
     *     @type \Google\Protobuf\FieldMask $update_mask
     *           Required. Indicates which fields in the provided subscription to update.
     *           Must be specified and non-empty.
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Google\Pubsub\V1\Pubsub::initOnce();
        parent::__construct($data);
    }

    /**
     * Required. The updated subscription object.
     *
     * Generated from protobuf field .google.pubsub.v1.Subscription subscription = 1 [(.google.api.field_behavior) = REQUIRED];
     * @return \Google\Cloud\PubSub\V1\Subscription|null
     */
    public function getSubscription()
    {
        return $this->subscription;
    }

    public function hasSubscription()
    {
        return isset($this->subscription);
    }

    public function clearSubscription()
    {
        unset($this->subscription);
    }

    /**
     * Required. The updated subscription object.
     *
     * Generated from protobuf field .google.pubsub.v1.Subscription subscription = 1 [(.google.api.field_behavior) = REQUIRED];
     * @param \Google\Cloud\PubSub\V1\Subscription $var
     * @return $this
     */
    public function setSubscription($var)
    {
        GPBUtil::checkMessage($var, \Google\Cloud\PubSub\V1\Subscription::class);
        $this->subscription = $var;

        return $this;
    }

    /**
     * Required. Indicates which fields in the provided subscription to update.
     * Must be specified and non-empty.
     *
     * Generated from protobuf field .google.protobuf.FieldMask update_mask = 2 [(.google.api.field_behavior) = REQUIRED];
     * @return \Google\Protobuf\FieldMask|null
     */
    public function getUpdateMask()
    {
        return $this->update_mask;
    }

    public function hasUpdateMask()
    {
        return isset($this->update_mask);
    }

    public function clearUpdateMask()
    {
        unset($this->update_mask);
    }

    /**
     * Required. Indicates which fields in the provided subscription to update.
     * Must be specified and non-empty.
     *
     * Generated from protobuf field .google.protobuf.FieldMask update_mask = 2 [(.google.api.field_behavior) = REQUIRED];
     * @param \Google\Protobuf\FieldMask $var
     * @return $this
     */
    public function setUpdateMask($var)
    {
        GPBUtil::checkMessage($var, \Google\Protobuf\FieldMask::class);
        $this->update_mask = $var;

        return $this;
    }

}


text:
package org.apache.camel.component.bean;

import java.util.HashMap;
import java.util.Map;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Message;
import org.apache.camel.TypeConverter;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.builder.ExpressionBuilder;

/**
 * Represents the strategy used to figure out how to map a message exchange to a POJO method invocation
 */
public final class DefaultParameterMappingStrategy implements ParameterMappingStrategy {

    public static final DefaultParameterMappingStrategy INSTANCE = new DefaultParameterMappingStrategy();

    private static final Map<Class<?>, Expression> MAP = new HashMap<>(6);

    static {
        MAP.put(Exchange.class, ExpressionBuilder.exchangeExpression());
        MAP.put(Message.class, ExpressionBuilder.inMessageExpression());
        MAP.put(Exception.class, ExpressionBuilder.exchangeExceptionExpression());
        MAP.put(TypeConverter.class, ExpressionBuilder.typeConverterExpression());
        MAP.put(Registry.class, ExpressionBuilder.registryExpression());
        MAP.put(CamelContext.class, ExpressionBuilder.camelContextExpression());
    };

    private DefaultParameterMappingStrategy() {
    }

    @Override
    public Expression getDefaultParameterTypeExpression(Class<?> parameterType) {
        return MAP.get(parameterType);
    }

}


text:
package com.palantir.atlasdb.keyvalue.cassandra.pool;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.palantir.conjure.java.client.config.ImmutablesStyle;
import org.immutables.value.Value;

@JsonDeserialize(as = ImmutableHostLocation.class)
@JsonSerialize(as = ImmutableHostLocation.class)
@ImmutablesStyle
@Value.Immutable
public interface HostLocation {

    @Value.Parameter
    String datacenter();

    @Value.Parameter
    String rack();

    static HostLocation of(String datacenter, String rack) {
        return ImmutableHostLocation.of(datacenter, rack);
    }

    default boolean isProbablySameRackAs(String datacenter, String rack) {
        return rack().equals(rack) && datacenter.startsWith(datacenter());
    }
}


text:
/**
 */
package gluemodel.CIM.IEC61968.Common.impl;

import gluemodel.CIM.IEC61968.Common.CommonPackage;
import gluemodel.CIM.IEC61968.Common.DateTimeInterval;
import gluemodel.CIM.IEC61968.Common.TimePoint;
import gluemodel.CIM.IEC61968.Common.TimeSchedule;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
import org.eclipse.emf.ecore.util.InternalEList;

/**
 *
 * An implementation of the model object 'Time Schedule'.
 *
 *

 * The following features are implemented:
 *

 *

 *
{@link gluemodel.CIM.IEC61968.Common.impl.TimeScheduleImpl#getRecurrencePattern Recurrence Pattern}

 *
{@link gluemodel.CIM.IEC61968.Common.impl.TimeScheduleImpl#getScheduleInterval Schedule Interval}

 *
{@link gluemodel.CIM.IEC61968.Common.impl.TimeScheduleImpl#isDisabled Disabled}

 *
{@link gluemodel.CIM.IEC61968.Common.impl.TimeScheduleImpl#getRecurrencePeriod Recurrence Period}

 *
{@link gluemodel.CIM.IEC61968.Common.impl.TimeScheduleImpl#getTimePoints Time Points}

 *
{@link gluemodel.CIM.IEC61968.Common.impl.TimeScheduleImpl#getOffset Offset}

 *

 *
 * @generated
 */
public class TimeScheduleImpl extends DocumentImpl implements TimeSchedule {
	/**
	 * The default value of the '{@link #getRecurrencePattern() Recurrence Pattern}' attribute.
	 *
	 *
	 * @see #getRecurrencePattern()
	 * @generated
	 * @ordered
	 */
	protected static final String RECURRENCE_PATTERN_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getRecurrencePattern() Recurrence Pattern}' attribute.
	 *
	 *
	 * @see #getRecurrencePattern()
	 * @generated
	 * @ordered
	 */
	protected String recurrencePattern = RECURRENCE_PATTERN_EDEFAULT;

	/**
	 * The cached value of the '{@link #getScheduleInterval() Schedule Interval}' reference.
	 *
	 *
	 * @see #getScheduleInterval()
	 * @generated
	 * @ordered
	 */
	protected DateTimeInterval scheduleInterval;

	/**
	 * The default value of the '{@link #isDisabled() Disabled}' attribute.
	 *
	 *
	 * @see #isDisabled()
	 * @generated
	 * @ordered
	 */
	protected static final boolean DISABLED_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isDisabled() Disabled}' attribute.
	 *
	 *
	 * @see #isDisabled()
	 * @generated
	 * @ordered
	 */
	protected boolean disabled = DISABLED_EDEFAULT;

	/**
	 * The default value of the '{@link #getRecurrencePeriod() Recurrence Period}' attribute.
	 *
	 *
	 * @see #getRecurrencePeriod()
	 * @generated
	 * @ordered
	 */
	protected static final float RECURRENCE_PERIOD_EDEFAULT = 0.0F;

	/**
	 * The cached value of the '{@link #getRecurrencePeriod() Recurrence Period}' attribute.
	 *
	 *
	 * @see #getRecurrencePeriod()
	 * @generated
	 * @ordered
	 */
	protected float recurrencePeriod = RECURRENCE_PERIOD_EDEFAULT;

	/**
	 * The cached value of the '{@link #getTimePoints() Time Points}' reference list.
	 *
	 *
	 * @see #getTimePoints()
	 * @generated
	 * @ordered
	 */
	protected EList<TimePoint> timePoints;

	/**
	 * The default value of the '{@link #getOffset() Offset}' attribute.
	 *
	 *
	 * @see #getOffset()
	 * @generated
	 * @ordered
	 */
	protected static final float OFFSET_EDEFAULT = 0.0F;

	/**
	 * The cached value of the '{@link #getOffset() Offset}' attribute.
	 *
	 *
	 * @see #getOffset()
	 * @generated
	 * @ordered
	 */
	protected float offset = OFFSET_EDEFAULT;

	/**
	 *
	 *
	 * @generated
	 */
	protected TimeScheduleImpl() {
		super();
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return CommonPackage.Literals.TIME_SCHEDULE;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public String getRecurrencePattern() {
		return recurrencePattern;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public void setRecurrencePattern(String newRecurrencePattern) {
		String oldRecurrencePattern = recurrencePattern;
		recurrencePattern = newRecurrencePattern;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.TIME_SCHEDULE__RECURRENCE_PATTERN, oldRecurrencePattern, recurrencePattern));
	}

	/**
	 *
	 *
	 * @generated
	 */
	public DateTimeInterval getScheduleInterval() {
		if (scheduleInterval != null && scheduleInterval.eIsProxy()) {
			InternalEObject oldScheduleInterval = (InternalEObject)scheduleInterval;
			scheduleInterval = (DateTimeInterval)eResolveProxy(oldScheduleInterval);
			if (scheduleInterval != oldScheduleInterval) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonPackage.TIME_SCHEDULE__SCHEDULE_INTERVAL, oldScheduleInterval, scheduleInterval));
			}
		}
		return scheduleInterval;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public DateTimeInterval basicGetScheduleInterval() {
		return scheduleInterval;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public void setScheduleInterval(DateTimeInterval newScheduleInterval) {
		DateTimeInterval oldScheduleInterval = scheduleInterval;
		scheduleInterval = newScheduleInterval;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.TIME_SCHEDULE__SCHEDULE_INTERVAL, oldScheduleInterval, scheduleInterval));
	}

	/**
	 *
	 *
	 * @generated
	 */
	public boolean isDisabled() {
		return disabled;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public void setDisabled(boolean newDisabled) {
		boolean oldDisabled = disabled;
		disabled = newDisabled;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.TIME_SCHEDULE__DISABLED, oldDisabled, disabled));
	}

	/**
	 *
	 *
	 * @generated
	 */
	public float getRecurrencePeriod() {
		return recurrencePeriod;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public void setRecurrencePeriod(float newRecurrencePeriod) {
		float oldRecurrencePeriod = recurrencePeriod;
		recurrencePeriod = newRecurrencePeriod;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.TIME_SCHEDULE__RECURRENCE_PERIOD, oldRecurrencePeriod, recurrencePeriod));
	}

	/**
	 *
	 *
	 * @generated
	 */
	public EList<TimePoint> getTimePoints() {
		if (timePoints == null) {
			timePoints = new EObjectWithInverseResolvingEList<TimePoint>(TimePoint.class, this, CommonPackage.TIME_SCHEDULE__TIME_POINTS, CommonPackage.TIME_POINT__TIME_SCHEDULE);
		}
		return timePoints;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public float getOffset() {
		return offset;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public void setOffset(float newOffset) {
		float oldOffset = offset;
		offset = newOffset;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.TIME_SCHEDULE__OFFSET, oldOffset, offset));
	}

	/**
	 *
	 *
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CommonPackage.TIME_SCHEDULE__TIME_POINTS:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getTimePoints()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CommonPackage.TIME_SCHEDULE__TIME_POINTS:
				return ((InternalEList<?>)getTimePoints()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PATTERN:
				return getRecurrencePattern();
			case CommonPackage.TIME_SCHEDULE__SCHEDULE_INTERVAL:
				if (resolve) return getScheduleInterval();
				return basicGetScheduleInterval();
			case CommonPackage.TIME_SCHEDULE__DISABLED:
				return isDisabled();
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PERIOD:
				return getRecurrencePeriod();
			case CommonPackage.TIME_SCHEDULE__TIME_POINTS:
				return getTimePoints();
			case CommonPackage.TIME_SCHEDULE__OFFSET:
				return getOffset();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 *
	 *
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PATTERN:
				setRecurrencePattern((String)newValue);
				return;
			case CommonPackage.TIME_SCHEDULE__SCHEDULE_INTERVAL:
				setScheduleInterval((DateTimeInterval)newValue);
				return;
			case CommonPackage.TIME_SCHEDULE__DISABLED:
				setDisabled((Boolean)newValue);
				return;
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PERIOD:
				setRecurrencePeriod((Float)newValue);
				return;
			case CommonPackage.TIME_SCHEDULE__TIME_POINTS:
				getTimePoints().clear();
				getTimePoints().addAll((Collection<? extends TimePoint>)newValue);
				return;
			case CommonPackage.TIME_SCHEDULE__OFFSET:
				setOffset((Float)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PATTERN:
				setRecurrencePattern(RECURRENCE_PATTERN_EDEFAULT);
				return;
			case CommonPackage.TIME_SCHEDULE__SCHEDULE_INTERVAL:
				setScheduleInterval((DateTimeInterval)null);
				return;
			case CommonPackage.TIME_SCHEDULE__DISABLED:
				setDisabled(DISABLED_EDEFAULT);
				return;
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PERIOD:
				setRecurrencePeriod(RECURRENCE_PERIOD_EDEFAULT);
				return;
			case CommonPackage.TIME_SCHEDULE__TIME_POINTS:
				getTimePoints().clear();
				return;
			case CommonPackage.TIME_SCHEDULE__OFFSET:
				setOffset(OFFSET_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PATTERN:
				return RECURRENCE_PATTERN_EDEFAULT == null ? recurrencePattern != null : !RECURRENCE_PATTERN_EDEFAULT.equals(recurrencePattern);
			case CommonPackage.TIME_SCHEDULE__SCHEDULE_INTERVAL:
				return scheduleInterval != null;
			case CommonPackage.TIME_SCHEDULE__DISABLED:
				return disabled != DISABLED_EDEFAULT;
			case CommonPackage.TIME_SCHEDULE__RECURRENCE_PERIOD:
				return recurrencePeriod != RECURRENCE_PERIOD_EDEFAULT;
			case CommonPackage.TIME_SCHEDULE__TIME_POINTS:
				return timePoints != null && !timePoints.isEmpty();
			case CommonPackage.TIME_SCHEDULE__OFFSET:
				return offset != OFFSET_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 *
	 *
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (recurrencePattern: ");
		result.append(recurrencePattern);
		result.append(", disabled: ");
		result.append(disabled);
		result.append(", recurrencePeriod: ");
		result.append(recurrencePeriod);
		result.append(", offset: ");
		result.append(offset);
		result.append(')');
		return result.toString();
	}

} //TimeScheduleImpl


text:
<?php
/**
 * Template part for displaying the page splash.
 * @package WordPress
 * @subpackage Kevin Lesht
 */

?>

<?php if ( is_front_page() || is_post_type_archive('projects') ) { ?>

The online portfolio of

<?php bloginfo( 'name' ); ?>

<?php bloginfo( 'description' ); ?>

<?php } elseif ( is_404() ) { ?>

404 Error

Whoops! Unfortunately, the page you've requested cannot be found.

<?php } else { ?>

			<?php

                $image = get_field('project_logo');

                if( $image ) {

                    echo wp_get_attachment_image( $image, $size, false, $attr = array( 'class'	=> "animated fadeIn" ) );

                }

            ?>

<?php echo get_field('project_description'); ?>

<?php } ?>


text:
//============================================================================
//
// Copyright (C) 2006-2022 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
//============================================================================

package org.talend.components.netsuite.client;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;
import org.talend.components.netsuite.AbstractNetSuiteTestBase;
import org.talend.components.netsuite.client.model.RecordTypeDesc;
import org.talend.components.netsuite.client.model.RecordTypeInfo;
import org.talend.components.netsuite.client.model.SearchRecordTypeDesc;
import org.talend.components.netsuite.client.model.TypeDesc;
import org.talend.components.netsuite.test.client.TestNetSuiteClientService;
import org.talend.components.netsuite.test.client.model.TestRecordTypeEnum;
import org.talend.daikon.NamedThing;

import com.netsuite.webservices.test.lists.accounting.Account;

/**
 *
 */
public class MetaDataSourceTest extends AbstractNetSuiteTestBase {

    private NetSuiteClientService<?> clientService = new TestNetSuiteClientService();

    private DefaultMetaDataSource metaDataSource;

    private TestCustomMetaDataSource customMetaDataSource;

    @Before
    public void setUp() throws Exception {
        super.setUp();

        metaDataSource = new DefaultMetaDataSource(clientService);
        metaDataSource.setCustomizationEnabled(true);

        customMetaDataSource = new TestCustomMetaDataSource(clientService);
        metaDataSource.setCustomMetaDataSource(customMetaDataSource);
    }

    @Test
    public void testGetTypeInfoByClass() {
        TypeDesc typeDesc = metaDataSource.getTypeInfo(Account.class);
        assertNotNull(typeDesc);
    }

    @Test
    public void testGetRecordTypes() {
        Collection<RecordTypeInfo> recordTypeInfos = metaDataSource.getRecordTypes();
        assertNotNull(recordTypeInfos);
        assertFalse(recordTypeInfos.isEmpty());

        Set<String> recordTypeNames = new HashSet<>();
        for (RecordTypeInfo recordTypeInfo : recordTypeInfos) {
            assertNotNull(recordTypeInfo);
            recordTypeNames.add(recordTypeInfo.getName());
        }

        for (RecordTypeDesc recordTypeDesc : TestRecordTypeEnum.values()) {
            assertTrue(recordTypeNames.contains(recordTypeDesc.getTypeName()));
        }

        for (RecordTypeInfo recordTypeInfo : customMetaDataSource.getCustomRecordTypes()) {
            assertTrue(recordTypeNames.contains(recordTypeInfo.getName()));
        }
    }

    @Test
    public void testGetSearchableTypes() {
        Collection<NamedThing> searchableTypeNamedThings = metaDataSource.getSearchableTypes();
        assertNotNull(searchableTypeNamedThings);
        assertFalse(searchableTypeNamedThings.isEmpty());

        Set<String> searchableTypeNames = new HashSet<>();
        for (NamedThing namedThing : searchableTypeNamedThings) {
            assertNotNull(namedThing);
            searchableTypeNames.add(namedThing.getName());
        }

        for (RecordTypeDesc recordTypeDesc : TestRecordTypeEnum.values()) {
            if (recordTypeDesc.getSearchRecordType() != null) {
                assertTrue(recordTypeDesc.getTypeName(), searchableTypeNames.contains(recordTypeDesc.getTypeName()));
            }
        }

        for (RecordTypeInfo recordTypeInfo : customMetaDataSource.getCustomRecordTypes()) {
            assertTrue(recordTypeInfo.getName(), searchableTypeNames.contains(recordTypeInfo.getName()));
        }
    }

    @Test
    public void testGetSearchRecordType() {
        SearchRecordTypeDesc searchRecordTypeDesc = metaDataSource.getSearchRecordType(TestRecordTypeEnum.ACCOUNT.getTypeName());
        assertNotNull(searchRecordTypeDesc);
        searchRecordTypeDesc = metaDataSource.getSearchRecordType(TestRecordTypeEnum.ACCOUNT.getTypeName());
        assertNotNull(searchRecordTypeDesc);

        searchRecordTypeDesc = metaDataSource.getSearchRecordType(TestRecordTypeEnum.CUSTOM_RECORD.getType());
        assertNotNull(searchRecordTypeDesc);
        searchRecordTypeDesc = metaDataSource.getSearchRecordType(TestRecordTypeEnum.CUSTOM_RECORD);
        assertNotNull(searchRecordTypeDesc);

        searchRecordTypeDesc = metaDataSource.getSearchRecordType(TestRecordTypeEnum.CUSTOM_TRANSACTION.getType());
        assertNotNull(searchRecordTypeDesc);
        searchRecordTypeDesc = metaDataSource.getSearchRecordType(TestRecordTypeEnum.CUSTOM_TRANSACTION);
        assertNotNull(searchRecordTypeDesc);

        assertNull(metaDataSource.getSearchRecordType(TestRecordTypeEnum.ENTITY_CUSTOM_FIELD.getTypeName()));
    }
}