What is data anonymization?

A guide to data anonymization: core techniques, anonymizing unstructured company data, and how de-identification supports AI development, data licensing, and software testing.

By Adam Kamor, PhD, Co-Founder & Head of Engineering at Tonic.ai
Updated June 2026
0 min read

Data anonymization, also called data de-identification, is the process of transforming data so the people in it can't be identified, directly or by linking what remains to other information. It removes or replaces direct identifiers, like names and email addresses, and indirect ones, like birth dates and job titles, while keeping the data useful for software testing, AI development, and data licensing. It applies to structured databases and to unstructured data like email, chat, and documents, where sensitive information can appear anywhere.

How data anonymization works

Data anonymization works by finding every value that could point back to a person, then removing or replacing it until no one in the dataset can be recognized. Those values fall into two groups. Direct identifiers name a person on their own: a full name, an email address, a Social Security number, a phone number. Quasi-identifiers, also called indirect identifiers, don't identify anyone alone but do in combination: a birth date, a ZIP code, a job title, an employer, a rare diagnosis. Both count as PII once they can be tied to someone, and anonymization has to handle both.

Quasi-identifiers are where anonymization efforts often fall short, because of re-identification by linkage. Someone takes the fields left in a dataset and combines them with outside information, like a public profile, a company org chart, or a voter roll. If only one person in the data is a 47-year-old VP of Finance in a particular city, removing her name didn't protect her. It works like a crossword puzzle: each remaining clue looks harmless, but enough intersecting clues leave only one answer that fits.

That's why every anonymization decision sits on a privacy–utility tradeoff. Delete or blur enough fields and no one can be re-identified, but the data may stop being worth using. A test suite can't exercise date logic with no dates, and a model can't learn who escalated a ticket if every name is gone. Keep too much and the linkage risk comes back. Good anonymization means transforming the right values, in the right way, for whoever will receive the result.

Where those values live changes how hard the job is. In structured data, sensitive values sit in labeled columns. You know the email column holds email addresses, so you can treat every row the same way. Semi-structured data, like JSON or XML, carries some labels in its keys, but those keys vary from source to source and often wrap free-text values that could contain anything. Unstructured data has no labels at all. An identifier can appear anywhere in free text, and it also shows up in places that are easy to overlook:

  • file names, folder paths, and URLs
  • metadata such as authors, recipients, and timestamps
  • usernames and IDs inside JSON exports from tools like Jira or Slack

For example, take one employee, Dana Ruiz. In the HR database, she's a single row with her name in the first_name and last_name columns. In an email, she's "Dana" in a greeting, "D. Ruiz" in a signature, and dana.ruiz@ in the header. In a ticketing export, she's druiz in the assignee field, and her performance review sits in a file named Ruiz_Dana_review.docx. Anonymizing the database row is straightforward. Finding and consistently replacing every other appearance is the harder problem, and one that is critical to solve before the data leaves your systems.

Diagram of one employee, Dana Ruiz, appearing in four places. In an HR database she sits in labeled first_name and last_name columns. Elsewhere her name is in unlabeled locations: an email’s To address, greeting, and signature; the assignee field of a JSON ticket export as “druiz”; and a file name, Ruiz_Dana_review.docx.

Anonymization vs. de-identification vs. pseudonymization (and masking, redaction, and scrubbing)

Anonymization and de-identification describe the same goal: data that no longer identifies the people in it. The difference between them most often comes down to who's speaking. De-identification is the term HIPAA uses and the one many privacy practitioners and AI labs reach for. Anonymization is the more colloquial term, and the one GDPR uses for data that has left its scope entirely. Both are correct. The distinctions that actually matter are between outcomes and techniques, and between transformations you can reverse and ones you can't.

Data masking, redaction, and tokenization are techniques, not outcomes. Each is a way to transform values, and whether the result counts as anonymized depends on how you apply it and what's left behind. Masking replaces values with realistic but fake ones and is a core practice in test data management. Redaction removes or blacks out values. Tokenization swaps values for tokens that can be mapped back, which makes it a form of pseudonymization unless the mapping is destroyed.

Scrubbing is a term with two meanings. In data engineering, data scrubbing usually means fixing data-quality errors like duplicates, malformed records, and inconsistent formats. Among people buying and selling company data, it often means removing sensitive information. Throughout data anonymization work, scrubbing means the second.

Anonymization vs de-identification vs pseudonymization: what each does, whether it is reversible, and typical use
Term What it does Reversible? Typical use
Anonymization Transforms data so no one can be identified, directly or by linkage No Releasing, sharing, or licensing data outside the organization
De-identification Same goal; the term HIPAA and many practitioners use No, when done to standard Healthcare data, AI training data, company data for licensing
Pseudonymization Replaces identifiers but keeps a link back to the person Yes, with additional information Internal analytics and processing with reduced exposure

Anonymization vs. pseudonymization

Pseudonymization replaces identifiers with stand-ins, such as a customer number in place of a name, but keeps a way back. A lookup table, an encryption key, or other information held separately can link the record to the person again. Under GDPR, pseudonymized data remains personal data for anyone who holds, or could reasonably obtain, the means to re-link it, which always includes the organization that pseudonymized it. Anonymized data has no route back for anyone, so it falls outside the regulation. Pseudonymization is still worth doing, since it reduces exposure and counts as a recognized safeguard. It just isn't anonymization, and treating the two as interchangeable is a common compliance mistake.

Data anonymization techniques

Data anonymization techniques fall into two families: those that remove or coarsen information, and those that replace it. Each technique buys privacy at some cost in utility, and the right choice depends on the entity type, the data format, and who receives the result. Many programs combine several.

Data anonymization techniques: what each does, what it is best for, and the resulting data utility
Technique What it does Best for Resulting data utility
Suppression and redaction Deletes a value or field, or replaces it with a blank or a placeholder like [NAME] Values no one downstream needs; documents shared outside the organization Low. Relationships, formats, and context disappear, and placeholders read unnaturally
Generalization and aggregation Coarsens values (age 47 becomes 40–49) or reports group totals instead of individual rows Statistical releases and reporting Low to medium. Detail and edge cases are lost
Masking Replaces values with fake, format-valid ones through substitution, scrambling, shuffling, or format-preserving masking, usually column by column Structured test and development databases Medium to high. Formats survive; consistency depends on configuration
Synthesis Generates realistic replacement values that fit the surrounding context and stay consistent wherever the same entity appears Unstructured text, company data, AI training data, and structured data that has to read naturally High. The data reads and behaves like the original
Tokenization Swaps values for tokens held in a mapping vault Systems that need to re-link data later High for joins, but reversible, so it’s pseudonymization unless the vault is destroyed
Perturbation and differential privacy Adds calibrated noise to values or query results; differential privacy mathematically bounds what any one record can reveal Aggregate statistics, analytics queries, some model training Varies. Aggregates stay useful; individual records stop being accurate

Masking and synthesis overlap, since both replace real values with fake ones. The simplest line between them is this: masking transforms a known field according to rules, while synthesis generates replacements that read naturally and stay consistent wherever the same entity appears. Masking fits when a schema tells you where the sensitive values are, and its configuration practices belong to test data management. Synthesis earns its place when context matters, as in an email where a replacement name has to agree with the greeting, the signature, and the sender's address.

You'll also run into k-anonymity, l-diversity, and t-closeness. These are less techniques than ways to measure re-identification risk in tabular data. K-anonymity, for example, checks that every combination of quasi-identifiers is shared by at least k records, so no one stands out. They're useful tests for a released table and much less useful for free text, where there are no fixed columns to count.

When anonymized data has to stay useful, consistent replacement beats deletion. Deletion leaves holes: a ticket thread where every participant is [NAME], a database whose foreign keys no longer join, a document whose meaning depended on who said what. Consistent replacement keeps the shape of the data. Each real person maps to one fictional person, every time, so joins still work, conversations still make sense, and patterns still hold. A test suite can still exercise the logic that depends on those values, a model can still learn who escalated to whom, and a buyer of the data still receives something that reads like a company doing its work. That consistency, whether you get it through masking or synthesis, is what separates anonymized data that's merely safe from anonymized data that's safe and worth using.

Anonymizing unstructured data

Anonymizing unstructured data is harder than anonymizing a database because no schema tells you where the sensitive information is. Classic techniques assume you can point at a column and apply a rule. Email, chat, tickets, and documents don't give you that. Three things make it a challenge:

  • There's no map of the sensitive data. Identifiers appear anywhere and in any form: full names, nicknames, email handles, initials in a signature, a phone number in the middle of a sentence.
  • Free text is only part of the surface. Identifiers also hide in attachments, file names, URLs, document metadata, and the usernames and IDs inside JSON exports from tools like Jira or Slack.
  • The same person recurs across files and systems. One customer appears in a support email, a chat thread, a CRM note, and a contract PDF, written differently each time.

Two requirements matter most in the approach used for anonymization. The first is high-recall detection. Recall measures how much of the sensitive information you actually found, and in de-identification a miss isn't a rounding error: a missed mention is real PII left in the data. Detection typically relies on named entity recognition models trained to find people, organizations, locations, and identifiers in text, often with a second verification pass.

The second is consistency across the corpus. One real person has to map to one replacement everywhere, so relationships survive. The person who opened a ticket is still the person who closed it, and the colleague named in an email is the same colleague in the chat thread. This is referential integrity for unstructured data, and it's what keeps the result usable for testing, training, and licensing. Here's what that looks like across an email and a chat message about the same people:

Before and after synthesis: an email and a chat message with names and companies replaced by consistent, realistic values
Source Before After
Email Hi Priya, can you send the renewal quote for Halvorsen Freight? Thanks, Marcus Bell Hi Leah, can you send the renewal quote for Oakmere Logistics? Thanks, Daniel Ortiz
Chat @pshah sent Halvorsen’s renewal to Marcus this morning @lmorgan sent Oakmere’s renewal to Daniel this morning

Priya becomes Leah in the email and @lmorgan in chat, Marcus becomes Daniel in both, and the customer becomes the same fictional company each time. A reader, a test, or a model sees the same working relationship the original described, with no real person in it.

Consistency at this level is measurable, and it's hard. Tonic Textual approaches it with Textual Graph Synthesis, which links every mention of a person or organization across a document set to the identity it belongs to, then replaces each identity with one synthetic identity that holds everywhere. In Tonic.ai's PrivacyBench benchmark, Textual Graph Synthesis led seven de-identification pipelines at 86.2% end to end, and replaced what it detected coherently 91.8% of the time, against 87.5% for the next-best pipeline. PrivacyBench scores the whole job, from raw email, Slack, and document exports to de-identified files, and its datasets and scoring code are public, so you can score your own pipeline against the same data.

Anonymizing company data for AI labs and data licensing

Anonymizing company data for AI labs means de-identifying a company's operational history so it can be licensed or sold to the labs building AI models. Companies hold years of email, chat, support tickets, documents, and CRM and HR records. That history shows how real work gets done, which is exactly what AI developers want, and it can't change hands while the people in it are identifiable.

The data usually becomes seed data for reinforcement learning (RL) environments, where AI agents practice doing real work, and examples for LLM post-training. Both uses depend on the data still reading like a real company after it's been de-identified.

Several parties take part in a typical deal. The data owner is the company whose history is being sold, sometimes one that's winding down and recovering value from its records. Brokers and licensors acquire the rights to that data and relicense it. Data labs buy company data as raw material for the environments and datasets they build and sell. The frontier labs are the end buyers. De-identification has to happen somewhere along that chain, and the options for who de-identifies company data [LINK TBD: multi-way comparison spoke on who should de-identify company data (in-house, data labs, independent third party), once live] include the data owner, a data lab working in house, and an independent third party. Each route carries different tradeoffs in margin, speed, and liability, which is why the question of who should de-identify company data is worth settling before a deal closes.

Labs require de-identification before they'll accept a corpus because they carry the risk once the data is inside a model. A model trained on a real email thread can memorize a real person's name, phone number, or medical detail and surface it later. Privacy obligations travel with the data too, and a lab that accepts identifiable personal data takes them on. The requirement can also extend beyond personal data. Confidential business information, like customer contract terms, pricing, unreleased product plans, or a partner's financials, can harm the data owner and the companies named in its records, so a deal-ready corpus may have that removed as well. When a lab asks for de-identified data, what de-identified means when you sell company data is specific: no one in the corpus can be identified, directly or by linkage.

What buyers of company data expect

De-identified isn't enough on its own. Labs pay for data that stays useful, and they want evidence of how it was handled. Clear tenets for de-identification in AI data licensing help sellers, providers, and labs agree on what that evidence looks like:

  • Consistency and coherence across every file. Each person and company maps to one replacement everywhere, so threads, tickets, and records still connect.
  • Accuracy standards agreed before work begins. Both sides know the detection and replacement quality the corpus has to meet, and how it will be measured.
  • Human review. A person checks every dataset rather than relying on automated detection alone.
  • A record of every transformation. What was detected, what replaced it, and how the result was measured, so the seller can show the lab and the data owner exactly what happened.
  • Certification. An attestation, from the de-identification provider or a third party, that the corpus meets the agreed standard.

Realistic replacement values are key for licensing data for model training. A corpus where every name is a placeholder loses much of what made it worth buying, while one where each person consistently becomes a believable stand-in still looks and feels like the original. Teams de-identifying company data for AI at volume find that consistency across the whole corpus, alongside detection, decides whether a dataset sells at full value.

Flow diagram of a company data deal. The data owner’s email, chat, tickets, documents, and CRM records pass through a de-identification step before reaching a broker or licensor, a data lab, and a frontier lab. The step requires consistent replacement, an agreed accuracy standard, human review, a transformation record, and certification.

Anonymizing data for RL environments, post-training, and AI development

De-identified real data is only useful for AI development if it still behaves like the original, and each use tests that differently. For building environments, training models, and calling hosted LLMs safely, the common requirement is replacement that's realistic and consistent, not just thorough. Broader questions about sourcing, labeling, and preparing AI training data follow the same logic.

RL environments

Real company data seeds RL environments where agents learn to do work, like triaging an inbox, resolving a ticket, or updating a CRM record. The anonymized data has to stay a coherent world. The same colleague appears in the email, the ticket, and the CRM record under the same replacement name, dates still line up, and replies still follow the messages they answer. Redaction breaks this immediately, since an agent can't learn to route a request to [NAME]. Inconsistent replacement breaks it more quietly. If the account manager has three different names across three systems, the environment teaches the agent that the world doesn't hold together. For environment seed data, a corpus where every identifier was caught but replaced inconsistently is still a broken world, so consistency deserves as much scrutiny as detection.

Post-training and fine-tuning

For LLM post-training and fine-tuning, realistic replacements keep the signal a model learns from. Placeholders and gaps teach the wrong patterns, since a model trained on text full of [REDACTED] tokens learns to produce them, and anything detection misses can be memorized and reproduced later. Replacement values also need to fit their context. A synthetic name should match the gender and nickname forms used in the thread, and a shifted date should keep the intervals between events, or the model learns relationships that never existed. Teams use Tonic Textual to prepare de-identified data for model training. Wellthy trains models on realistic, de-identified care-team messages created with Textual, and achieved a 50% reduction in flagged care team actions. Ontra uses Textual to consistently de-identify and synthesize both structured and unstructured data, a foundational part of its AI strategy.

LLM privacy proxy

An LLM privacy proxy protects sensitive data at inference time, scrubbing it on its way into a prompt or a third-party model, so teams can use hosted models without sending real names, account numbers, or health details. It can sit in front of every model call or run as a callable step inside a developer's own tools. A national tax services company deployed Textual as an LLM privacy layer, which unblocked its AI initiatives. The same approach applies to agent traces, the transcripts, tool calls, and logs that agents produce, which can be de-identified so they can be retained and analyzed.

Realistic replacement helps at inference time too. A prompt where names and accounts become believable stand-ins still reads naturally to the model, so its answer stays useful, while a prompt full of masks and placeholders often produces a weaker response.

Anonymizing production data for software testing

Anonymizing production data for software testing gives developers production-like data in lower environments without exposing the customers in it. Test environments need data that behaves like production, with the same edge cases, distributions, and messy records. Staging servers and developer laptops don't carry production's controls, so anonymization is what makes that data safe to move.

The requirements are stricter than they look. Anonymization has to preserve referential integrity across tables and databases. If a customer ID is replaced in the orders table, the same replacement has to appear in invoices, support tickets, and the analytics warehouse, or joins fail and tests break for reasons that have nothing to do with the code. It also has to hold across refreshes, so a given customer's replacement this week matches last week's and saved test cases and bug reproductions keep working. Deterministic, seeded replacement is how teams get consistency across tables and refreshes.

Format matters as much as consistency. A replaced phone number, card number, or national ID still has to pass the validation your application runs, or tests fail at the input layer before they reach the logic you meant to test. Distributions matter too. If every replaced customer lands in the same city or the same age band, performance tests and analytics queries stop reflecting how production behaves.

Subsetting reduces how much sensitive data moves at all. Instead of copying an entire production database, you extract a smaller, referentially intact slice that covers the scenarios you need to test. Smaller datasets are faster to provision, cheaper to store, and leave less sensitive data in lower environments. They also refresh faster, which helps test data keep pace as the production schema changes. The masking and provisioning practices behind this workflow are covered in depth under test data management.

The payoff shows up in delivery speed. Patterson cut test data provisioning time by 75% with Tonic Structural, with PHI kept out of developer workflows. Teams building testing and QA pipelines often go one step further with a hybrid approach, combining de-identification of real data with synthetic data generation so they can de-identify what exists and generate what doesn't.

Data anonymization and privacy law

Privacy laws treat properly anonymized data differently from personal data, but each sets the bar in its own terms. Most teams meet that bar through GDPR, HIPAA, and CCPA, and the differences between them matter when one dataset is subject to more than one.

GDPR

Anonymous data falls outside GDPR's scope. Pseudonymized data stays inside it for anyone who can re-link it. Under the regulation, whether a person is identifiable depends on all the means reasonably likely to be used to identify them, taking into account cost, time, and available technology. European data protection authorities frame the practical tests as three questions. Can a record be singled out? Can it be linked to other records about the same person? Can something about a person be inferred from it? If the answer to any of them is yes, the data is likely still personal data. The Court of Justice of the EU has also held that sufficiently pseudonymized data can be personal data for the organization holding the key, but not for a recipient with no realistic means to reverse it. Identifiability depends on who holds the data, which matters whenever pseudonymized data is shared or sold, and it shapes what counts as de-identified data in a company data deal. Meeting this bar is one part of broader GDPR compliance.

HIPAA

HIPAA uses the term de-identification and defines two methods for it. Safe Harbor requires removing 18 specified identifiers, including names, most geographic detail smaller than a state, all date elements except the year, and contact details, and the covered entity must have no actual knowledge that what remains could identify someone. Expert Determination relies on a qualified expert applying statistical and scientific methods to determine that the risk of re-identification is very small. Safe Harbor is simple to apply but blunt, since it strips dates and locations many uses need. Expert Determination preserves more of the data's utility when the expert's analysis supports it. The HHS guidance on HIPAA de-identification methods covers both in detail, and both sit inside broader HIPAA compliance obligations.

CCPA

CCPA has its own deidentified standard. Information is deidentified when it can't reasonably be used to infer information about, or otherwise be linked to, a particular consumer, and the business holding it takes reasonable measures to keep it that way, publicly commits not to re-identify it, and contractually requires recipients to do the same. The standard combines a technical test with organizational commitments, which makes the process around the data as important as the data itself.

‍

Across all three, compliance is a property of the overall program, not of a tool inside it. Tools for compliant data de-identification support that program. Documentation, access controls, contracts, and review are what make it defensible.

How to anonymize data: a five-step process

At a high level, you can anonymize data with the same five steps whether you're preparing a test database, a training corpus, or a dataset for sale. Each step narrows the risk and protects the data's usefulness.

  1. Inventory where sensitive data lives. Start with the sources in scope, like databases, file shares, email, chat, ticketing systems, and documents, then detect where sensitive values sit inside each one. A useful inventory works at the level of the value: which columns in which tables hold identifiers, which fields in a ticketing export carry names, and which documents mention a customer, and where. That means scanning the data itself, since a notes column or a free-text comment field can hold names, account numbers, or diagnoses no schema would predict. The result is a map of every entity type and every place it appears, which drives each step that follows.
  1. Define the purpose and the recipient. Who gets the data determines the risk. A dataset that stays inside a locked-down analytics environment carries different exposure than one handed to an offshore test team, and both differ from a corpus licensed to an outside lab. The recipient also determines which law applies and how much detail the data has to keep.
  1. Choose a technique for each entity type. Names, email addresses, and account numbers usually call for consistent replacement. Dates may need shifting by a consistent offset per person so intervals still make sense. Fields no one needs can simply be suppressed. Deciding per entity type keeps you from applying one blunt rule to everything.
  1. Validate both privacy and utility. On the privacy side, measure detection recall against human-annotated samples, because every miss is real PII left behind, and have a person review output before it ships. Detection quality varies widely between engines. Against human-annotated data in Tonic.ai's PrivacyBench benchmark, Tonic Textual caught 93.0% of PII, 6 points more than any other engine tested, while keeping precision above 90%. On the utility side, run the tests, queries, or training jobs the data is for and confirm they still behave as expected.
  1. Document and, where needed, certify the result. Record what was detected, what replaced it, and how the result was measured. For regulated or licensed data, an Expert Determination or third-party certification turns that record into an attestation others can rely on.

Comparing data anonymization tools [LINK TBD: best data anonymization tools listicle spoke once live] against these five steps, especially detection recall and consistency across files, separates tools built for unstructured data from tools built only for columns.

How Tonic de-identifies data for testing, AI development, and licensing

Tonic approaches data de-identification [LINK TBD: de-identification capabilities page once live] with consistent, realistic replacement, matched to the type of data and the job it needs to do. Each product is purpose-built for specific types of data and anonymization use cases, and some use cases, like testing and development, are served by more than one.

Tonic Textual de-identifies unstructured data. Its proprietary NER models detect sensitive information across email, chat, documents, and other files, and Textual replaces what it finds with realistic, consistent synthetic values. Textual maps the sensitive data you hold, and where it sits, before anything is transformed, so you can scope a de-identification effort accurately from the start. It records what it detected and what replaced it, giving you a reviewable account of every change. Textual Graph Synthesis gives every real person and organization one synthetic identity across a whole document set, and you can configure consistent synthesis for each entity type.

For company data headed to AI labs, Tonic.ai provides data de-identification as an independent third party, with Textual as the engine. Accuracy standards are agreed in advance, a human reviews every dataset, and every transformation is recorded. Tonic.ai certifies every dataset it de-identifies, and additional certification by a third party is available.

For AI development, Textual runs as software your team operates, including as a callable step through its MCP server, so de-identification happens inside the tools your developers already use.

Tonic Structural de-identifies databases for testing and development while preserving referential integrity across tables and databases, with subsetting to keep lower environments lean. Its built-in agent turns configuring sensitivity detection, generators, and subsets into a conversation rather than hours of manual setup.

Likewise for the testing and development use case, Tonic Fabricate provides a hybrid synthetic data generation and data masking offering, so you can mask the data you have and generate the data you don't in one platform. Fabricate's agent reviews the columns in your database, identifies the sensitive data, and drafts a masking plan you can read in plain language, adjust, and approve. The approved plan becomes a reusable workflow you can run again and customize as your schema changes, and every run produces a privacy report. Fabricate supports subsetting alongside masking, and because masking and generation live together, you can scale up masked data with generation to reach the volume your tests need. Teams that first need to know where their sensitive data lives can run Fabricate's privacy scan on its own.

For healthcare data, Tonic.ai provides de-identification that meets HIPAA requirements, with certification available through an independent Expert Determination partner.

Connect with our team to explore which solution best meets your data anonymization needs.

Frequently asked questions

No. Anonymization, or de-identification, transforms real records to strip out identifiers, while synthesis generates net-new records that never belonged to a real person. They solve different problems and are often used together — de-identification when you need a safer copy of real data, and synthesis with Tonic Fabricate when you need net-new data or more of it than production holds.

For software testing, often yes; for AI training, increasingly so. In a Tonic.ai benchmark, a model fine-tuned only on synthetic data beat o3 on real-world email tasks without seeing a real email. It fits best in model training and testing, where realistic data matters more than literally real data.

It depends on re-identification risk. These frameworks turn on whether a real individual can be identified from the data. Net-new data generated with Tonic Fabricate contains no real records, so re-identification isn't possible; data modeled on sensitive source data should be validated to confirm the same before you rely on it.

When you don't have usable production data, or you need more volume, variety, or net-new scenarios than it holds. De-identified data fits when you already have production data and need its exact real-world shape. For testing and QA, teams often use both — de-identified data for fidelity, synthetic data for scale and coverage.

As faithful as the method and source allow. Generating from a model of an existing dataset yields the highest fidelity, because the agent profiles the source and preserves its distributions, correlations, and relationships. From-scratch generation is as realistic as the rules and patterns you describe.